একক তালিকা থেকে জোড়


100

প্রায়শই যথেষ্ট, আমি জোড়া দ্বারা একটি তালিকা প্রক্রিয়া করার প্রয়োজনীয়তা খুঁজে পেয়েছি। আমি ভাবছিলাম যে এটি করার অজগর এবং দক্ষ উপায় কোনটি হবে এবং এটি গুগলে খুঁজে পেয়েছি:

pairs = zip(t[::2], t[1::2])

আমি ভেবেছিলাম যে এটি যথেষ্ট অজগর, তবে সাম্প্রতিক আলোচনার পরে আইডিয়ামগুলি দক্ষতার সাথে জড়িত , আমি কিছু পরীক্ষা করার সিদ্ধান্ত নিয়েছি:

import time
from itertools import islice, izip

def pairs_1(t):
    return zip(t[::2], t[1::2]) 

def pairs_2(t):
    return izip(t[::2], t[1::2]) 

def pairs_3(t):
    return izip(islice(t,None,None,2), islice(t,1,None,2))

A = range(10000)
B = xrange(len(A))

def pairs_4(t):
    # ignore value of t!
    t = B
    return izip(islice(t,None,None,2), islice(t,1,None,2))

for f in pairs_1, pairs_2, pairs_3, pairs_4:
    # time the pairing
    s = time.time()
    for i in range(1000):
        p = f(A)
    t1 = time.time() - s

    # time using the pairs
    s = time.time()
    for i in range(1000):
        p = f(A)
        for a, b in p:
            pass
    t2 = time.time() - s
    print t1, t2, t2-t1

এগুলি আমার কম্পিউটারে ফলাফল ছিল:

1.48668909073 2.63187503815 1.14518594742
0.105381965637 1.35109519958 1.24571323395
0.00257992744446 1.46182489395 1.45924496651
0.00251388549805 1.70076990128 1.69825601578

যদি আমি তাদের সঠিকভাবে ব্যাখ্যা করছি তবে এর অর্থ এই যে পাইথনে তালিকাগুলি, তালিকা সূচীকরণ এবং তালিকা স্লাইসিং কার্যকর করা খুব কার্যকর। এটি আরামদায়ক এবং অপ্রত্যাশিত উভয়ই ফলাফল।

জোড়ের তালিকায় ট্র্যাভারিংয়ের আরও কি কোনও "ভাল" উপায় আছে?

মনে রাখবেন যে তালিকার একটি অদ্ভুত সংখ্যক উপাদান রয়েছে তবে শেষেরটি কোনও জোড়াতে থাকবে না।

সমস্ত উপাদান অন্তর্ভুক্ত রয়েছে তা নিশ্চিত করার সঠিক উপায় কোনটি?

আমি পরীক্ষাগুলির উত্তরগুলি থেকে এই দুটি পরামর্শ যুক্ত করেছি:

def pairwise(t):
    it = iter(t)
    return izip(it, it)

def chunkwise(t, size=2):
    it = iter(t)
    return izip(*[it]*size)

এগুলি ফলাফল:

0.00159502029419 1.25745987892 1.25586485863
0.00222492218018 1.23795199394 1.23572707176

এখনও পর্যন্ত ফলাফল

সর্বাধিক অজগর এবং খুব দক্ষ:

pairs = izip(t[::2], t[1::2])

সবচেয়ে দক্ষ এবং খুব পাইথোনিক:

pairs = izip(*[iter(t)]*2)

এই মুহুর্তে আমার এক মুহুর্ত লেগেছিল যে প্রথম উত্তরটি দুটি পুনরুক্তি ব্যবহার করে যখন দ্বিতীয়টি একক ব্যবহার করে।

বিজোড় সংখ্যক উপাদানের সাথে সিকোয়েন্সগুলি মোকাবেলা করার জন্য, পরামর্শটি হ'ল মূল সিকোয়েন্সটি একটি উপাদান ( None) যুক্ত করে যুক্ত করা হবে যা পূর্ববর্তী শেষ উপাদানটির সাথে যুক্ত হয়ে যায়, এমন কিছু যা অর্জন করা যায় itertools.izip_longest()

অবশেষে

দ্রষ্টব্য, পাইথন 3.x এ, zip()যেমন আচরণ করে itertools.izip()এবং itertools.izip() চলে গেছে।


আর: "সঠিক পথ" - কোনও "সঠিক" উপায় নেই! এটি নির্ভর করে ব্যবহারের ক্ষেত্রে।
অ্যান্ড্রু জাফ

@ অ্যান্ড্রু জাফি আমি এই ক্ষেত্রে "সেরা" এর মানদণ্ডটি দিয়েছি: দক্ষ এবং পাইথোনিক।
অপালালা

@ অ্যাপালালা: আমি বলতে চাইছি বিজোড় সংখ্যা থাকার ফলাফল ব্যবহারের উপর নির্ভর করে। উদাহরণস্বরূপ: আপনি কেবলমাত্র শেষ উপাদানটি ছেড়ে যেতে পারেন, বা একটি নির্দিষ্ট পরিচিত ডামি উপাদান যুক্ত করতে পারেন, বা শেষটিকে নকল করতে পারেন
অ্যান্ড্রু জাফি

4
@ অ্যাপালালা: কারণ আপনি timeitমডিউলটির পরিবর্তে কিছু আম্বো-জাম্বো ব্যবহার করছেন ।
সাইলেন্টগোস্ট

4
এন-সদৃশ: শুধু একটি দ্রুত অনুসন্ধান: stackoverflow.com/questions/4501636 , stackoverflow.com/questions/4170295 , stackoverflow.com/questions/434287
tokland

উত্তর:


52

এটি করার আমার প্রিয় উপায়:

from itertools import izip

def pairwise(t):
    it = iter(t)
    return izip(it,it)

# for "pairs" of any length
def chunkwise(t, size=2):
    it = iter(t)
    return izip(*[it]*size)

আপনি যখন সমস্ত উপাদানকে যুক্ত করতে চান তখন আপনার অবশ্যই একটি পূর্ণ মূল্য প্রয়োজন হতে পারে:

from itertools import izip_longest
def blockwise(t, size=2, fillvalue=None):
    it = iter(t)
    return izip_longest(*[it]*size, fillvalue=fillvalue)

প্রথম (জোড়াযুক্ত) ফাংশনটি দ্বিতীয় পুনরুক্তকারীর ক্লোনিং এবং অগ্রযাত্রা অনুপস্থিত মনে হচ্ছে। দেখুন itertoolsরেসিপি অধ্যায়।
অপালালা

@ অ্যাপালালা: জিপ দু'বার একই পুনরাবৃত্তিকে এগিয়ে নিয়ে যায়।
জোচেন রিটেল

অবশ্যই, আপনি সঠিক, এবং জোড়া এখন পর্যন্ত সবচেয়ে দক্ষ, কেন জানি না।
অপালালা

4
আমি এই সমাধানটি পছন্দ করি: এটি অলস এবং এটি পুনরাবৃত্তিকারীদের স্থিতিশীলতার দুর্দান্ত প্রভাবকে কাজে লাগায়। এমনকি আপনি এটিকে ওয়ান-লাইনারও বানাতে পারেন, যদিও সম্ভবত পঠনযোগ্যতার ব্যয়ে:izip(*[iter(t)]*size)
মুর

আপনার দ্বিতীয় সমাধানের জন্য, আপনি যদি পারফর্মেন্সের পরে যাচ্ছেন তবে কোনও তালিকা তৈরি করা এড়াতে চান না?
সর্বোচ্চ

41

আমি বলতে চাই যে আপনার প্রারম্ভিক সমাধান pairs = zip(t[::2], t[1::2])সেরা এক কারণ এটি সবচেয়ে সহজ পদ্ধিতি হল পড়া (এবং পাইথন 3 হয় zipস্বয়ংক্রিয়ভাবে একটি তালিকা পরিবর্তে একটি পুনরুক্তিকারীর ফেরৎ)।

সমস্ত উপাদান অন্তর্ভুক্ত রয়েছে তা নিশ্চিত করার জন্য, আপনি কেবল তালিকাটি বাড়িয়ে দিতে পারেন None

তারপরে, যদি তালিকার একটি বিজোড় সংখ্যক উপাদান থাকে তবে শেষের জুটিটি হবে (item, None)

>>> t = [1,2,3,4,5]
>>> t.append(None)
>>> zip(t[::2], t[1::2])
[(1, 2), (3, 4), (5, None)]
>>> t = [1,2,3,4,5,6]
>>> t.append(None)
>>> zip(t[::2], t[1::2])
[(1, 2), (3, 4), (5, 6)]

6

আমি ছোট অস্বীকৃতি দিয়ে শুরু করি - নীচের কোডটি ব্যবহার করবেন না। এটি মোটেই পাইথোনিক নয়, আমি কেবল মজাদার জন্য লিখেছি। এটি @ THC4k pairwiseফাংশনের অনুরূপ তবে এটি ব্যবহার করে iterএবং lambdaবন্ধ হয়ে যায়। এটি itertoolsমডিউল ব্যবহার করে না এবং সমর্থন করে না fillvalue। আমি এটি এখানে রেখেছি কারণ কেউ এটি আকর্ষণীয় বলে মনে করতে পারে:

pairwise = lambda t: iter((lambda f: lambda: (f(), f()))(iter(t).next), None)

4

যতদূর যায় পাইথোনিক হিসাবে, আমি বলতে চাই পাইথন সোর্স ডক্সে সরবরাহিত রেসিপিগুলি (যার মধ্যে বেশিরভাগ দেখতে @ জোছানরিটজেল প্রদত্ত জবাবগুলির মতো দেখায়) সম্ভবত আপনার সেরা বাজি;)

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
    args = [iter(iterable)] * n
    return izip_longest(fillvalue=fillvalue, *args)

আধুনিক অজগরটিতে আপনাকে কেবল zip_longest(*args, fillvalue=fillvalue) সংশ্লিষ্ট ডক পৃষ্ঠা অনুসারে ব্যবহার করতে হবে ।


2

জোড়ের তালিকায় ট্র্যাভারিংয়ের আরও কি কোনও "ভাল" উপায় আছে?

আমি নিশ্চিত করে বলতে পারি না তবে আমি সন্দেহ করি: অন্য কোনও ট্র্যাভারসাল-এ আরও পাইথন কোড অন্তর্ভুক্ত থাকবে যার ব্যাখ্যা দিতে হবে। জিপ () এর মতো অন্তর্নির্মিত ফাংশন সি তে লেখা থাকে যা অনেক দ্রুত is

সমস্ত উপাদান অন্তর্ভুক্ত রয়েছে তা নিশ্চিত করার সঠিক উপায় কোনটি?

তালিকার দৈর্ঘ্য যাচাই করুন এবং যদি এটি বিজোড় হয় ( len(list) & 1 == 1), তালিকাটি অনুলিপি করুন এবং একটি আইটেম যুক্ত করুন।


2
>>> my_list = [1,2,3,4,5,6,7,8,9,10]
>>> my_pairs = list()
>>> while(my_list):
...     a = my_list.pop(0); b = my_list.pop(0)
...     my_pairs.append((a,b))
... 
>>> print(my_pairs)
[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]

সূচিপত্র: খালি তালিকা থেকে পপ করুন
এইচকিউসার

@ এইচকিউসার নিশ্চিত, তালিকায় আপনার যদি বিজোড় সংখ্যক আইটেম থাকে তবে আপনি সেই ত্রুটিটি পাবেন। আপনার জোড়া আছে কিনা তা নিশ্চিত করে জানতে হবে বা এই ত্রুটি শর্তটি পরীক্ষা করে দেখুন।
ওয়াটারমোলিকুল


0

এখানে জেনারেটর ব্যবহার করে জোড়া / পা তৈরির একটি উদাহরণ। জেনারেটর স্ট্যাক সীমা থেকে মুক্ত

def pairwise(data):
    zip(data[::2], data[1::2])

উদাহরণ:

print(list(pairwise(range(10))))

আউটপুট:

[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]

ফাঁসির সময়ের তুলনা?
অ্যালান

মূল তালিকার বেশিরভাগ সংখ্যা দুটি টিপলগুলিতে প্রদর্শিত হওয়ায় তালিকাটি জোড়ায় ভাঙা হয়নি। প্রত্যাশিত আউটপুটটি হল[(0, 1), (2, 3), (4, 5)....
অপালালা

@ আপালালাকে নির্দেশ করার জন্য আপনাকে ধন্যবাদ আমি সঠিক আউটপুট সরবরাহ করার জন্য কোডটি ঠিক করেছি
ভ্লাদ বেজডেন

zip()ইতিমধ্যে পাইথন ৩.x, @ ভ্লাদবেজডেন
অপালালা

তালিকার দৈর্ঘ্য যদি না হয় তবে সর্বশেষ উপাদানটি বাদ দেওয়া হবে
ড্যানিল ওখলোপকভ

-1

যদি কারও উত্তরটির অ্যালগরিদম অনুযায়ী প্রয়োজন হয়, তবে তা এখানে রয়েছে:

>>> def getPairs(list):
...     out = []
...     for i in range(len(list)-1):
...         a = list.pop(0)
...         for j in a:
...             out.append([a, j])
...     return b
>>> 
>>> k = [1, 2, 3, 4]
>>> l = getPairs(k)
>>> l
[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]

তবে মনে রাখবেন যে আপনার আসল তালিকাটি এটির শেষ উপাদানটিতেও হ্রাস পাবে, কারণ আপনি popএটি ব্যবহার করেছিলেন।

>>> k
[4]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.