পাইথনে, একই দৈর্ঘ্যের দুটি তালিকার ইন্টারলিভ করার ভাল উপায় কী?
বলুন আমি দিয়েছি [1,2,3]এবং [10,20,30]। আমি এগুলিতে রূপান্তর করতে চাই [1,10,2,20,3,30]।
পাইথনে, একই দৈর্ঘ্যের দুটি তালিকার ইন্টারলিভ করার ভাল উপায় কী?
বলুন আমি দিয়েছি [1,2,3]এবং [10,20,30]। আমি এগুলিতে রূপান্তর করতে চাই [1,10,2,20,3,30]।
উত্তর:
প্রশ্ন পোস্ট করে, আমি বুঝতে পেরেছি যে আমি কেবল নিম্নলিখিতগুলি করতে পারি:
[val for pair in zip(l1, l2) for val in pair]
কোথায় l1এবং l2দুটি তালিকা।
ইন্টারলিভ করার জন্য যদি এন তালিকাগুলি থাকে, তবে
lists = [l1, l2, ...]
[val for tup in zip(*lists) for val in tup]
izip_longestপাইথন 2 এবং পাইথন 3 এর জন্য ব্যবহার করুন with ফলাফল সহzip_longest[val for pair in itertools.zip_longest(l1, l2) for val in pair]['a', 'b', 'a', 'b', 'a', 'b', None, 'b', None, 'b', None, 'b']
পাইথন> = 2.3 এর জন্য এখানে প্রসারিত স্লাইস সিনট্যাক্স রয়েছে :
>>> a = [0, 2, 4, 6, 8]
>>> b = [1, 3, 5, 7, 9]
>>> c = a + b
>>> c[::2] = a
>>> c[1::2] = b
>>> c
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
c = a + bসঠিক দৈর্ঘ্যের একটি নতুন তালিকা তৈরি করার জন্য লাইনটি একটি সহজ উপায় হিসাবে ব্যবহৃত হয় (এই পর্যায়ে, এর বিষয়বস্তুগুলি গুরুত্বপূর্ণ নয়)। পরের দুটি লাইন আন্তঃলিখনের আসল কাজ করে aএবং b: প্রথমটি aসমস্ত সমান-তালিকাযুক্ত সূচকের উপাদানগুলি নির্ধারণ করে c; দ্বিতীয়টি bসমস্ত বিজোড়-সংখ্যাযুক্ত সূচকের উপাদানগুলি নির্ধারিত করে c।
দেওয়া হয়েছে
a = [1, 2, 3]
b = [10, 20, 30]
c = [100, 200, 300, 999]
কোড
সমান দৈর্ঘ্যের তালিকাগুলি ধরে নেওয়া, আপনি itertools.chainএবং এর সাথে একটি আন্তঃবিস্তারিত তালিকা পেতে পারেন zip:
import itertools
list(itertools.chain(*zip(a, b)))
# [1, 10, 2, 20, 3, 30]
বিকল্প
অসম তালিকা সহ আরও সাধারণভাবে ব্যবহার করুন zip_longest(প্রস্তাবিত):
[x for x in itertools.chain(*itertools.zip_longest(a, c)) if x is not None]
# [1, 100, 2, 200, 3, 300, 999]
অনেকগুলি তালিকা নিরাপদে আন্তঃলিপ্ত থাকতে পারে:
[x for x in itertools.chain(*itertools.zip_longest(a, b, c)) if x is not None]
# [1, 10, 100, 2, 20, 200, 3, 30, 300, 999]
একটি লাইব্রেরি যা roundrobinইটারল্টুল রেসিপি সহ জাহাজ সরবরাহ করে interleaveএবং interleave_longest।
import more_itertools
list(more_itertools.roundrobin(a, b))
# [1, 10, 2, 20, 3, 30]
list(more_itertools.interleave(a, b))
# [1, 10, 2, 20, 3, 30]
list(more_itertools.interleave_longest(a, c))
# [1, 100, 2, 200, 3, 300, 999]
yield from
অবশেষে পাইথন 3-তে আকর্ষণীয় কিছু জন্য (যদিও প্রস্তাবিত নয়):
list(filter(None, ((yield from x) for x in zip(a, b))))
# [1, 10, 2, 20, 3, 30]
list([(yield from x) for x in zip(a, b)])
# [1, 10, 2, 20, 3, 30]
+ + ব্যবহার করে কি ইনস্টলpip install more_itertools
আমার বিভিন্ন মাপের তালিকা সহ এটি করার একটি উপায়ের প্রয়োজন ছিল যা গৃহীত উত্তরটি সম্বোধন করে না।
আমার দ্রষ্টব্য একটি জেনারেটর ব্যবহার করে এবং এর ব্যবহারের কারণে এর ব্যবহারটি কিছুটা সুন্দর লাগছে:
def interleave(l1, l2):
iter1 = iter(l1)
iter2 = iter(l2)
while True:
try:
if iter1 is not None:
yield next(iter1)
except StopIteration:
iter1 = None
try:
if iter2 is not None:
yield next(iter2)
except StopIteration:
iter2 = None
if iter1 is None and iter2 is None:
raise StopIteration()
এবং এর ব্যবহার:
>>> a = [1, 2, 3, 4, 5]
>>> b = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> list(interleave(a, b))
[1, 'a', 2, 'b', 3, 'c', 4, 'd', 5, 'e', 'f', 'g']
>>> list(interleave(b, a))
['a', 1, 'b', 2, 'c', 3, 'd', 4, 'e', 5, 'f', 'g']
roundrobinথেকে রেসিপি itertoolsমডিউল এই একটি সাধারণ এক্সটেনশান।
বিকল্প:
>>> l1=[1,2,3]
>>> l2=[10,20,30]
>>> [y for x in map(None,l1,l2) for y in x if y is not None]
[1, 10, 2, 20, 3, 30]
এটি কাজ করে কারণ মানচিত্র সমান্তরাল তালিকায় কাজ করে। এটি ২.২ এর আওতায় একই কাজ করে । নিজেই, Noneযাকে ডাকা ফাংশন হিসাবে, mapটিপলগুলির একটি তালিকা তৈরি করে:
>>> map(None,l1,l2,'abcd')
[(1, 10, 'a'), (2, 20, 'b'), (3, 30, 'c'), (None, None, 'd')]
তারপরে কেবল টিপলগুলির তালিকাটি সমতল করুন।
অবশ্যই সুবিধাটি হ'ল map যে কোনও সংখ্যক তালিকার পক্ষে কাজ করবে এবং সেগুলি বিভিন্ন দৈর্ঘ্যের হলেও কার্যকর হবে:
>>> l1=[1,2,3]
>>> l2=[10,20,30]
>>> l3=[101,102,103,104]
>>> [y for x in map(None,l1,l2,l3) for y in x if y in not None]
[1, 10, 101, 2, 20, 102, 3, 30, 103, 104]
if yফিল্টার আউট 0খুব if y is not Noneকম ভঙ্গুর হবে।
আমি আইসের সমাধানটি সবচেয়ে পছন্দ করি। এখানে আমার মনে হয় অন্যভাবে ২.২-তে কাজ করা উচিত:
>>> x=range(3)
>>> x
[0, 1, 2]
>>> y=range(7,10)
>>> y
[7, 8, 9]
>>> sum(zip(x,y),[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
>>> sum(map(list,zip(x,y)),[])
[0, 7, 1, 8, 2, 9]
এবং আরও একটি উপায়:
>>> a=[x,y]
>>> [a[i][j] for j in range(3) for i in (0,1)]
[0, 7, 1, 8, 2, 9]
এবং:
>>> sum((list(i) for i in zip(x,y)),[])
[0, 7, 1, 8, 2, 9]
[el for el in itertools.chain(*itertools.izip_longest([1,2,3], [4,5])) if el is not None]
যতক্ষণ না আপনার Noneকাছে রাখতে চান যে আপনি রাখতে চান
"পাইথনের একই দৈর্ঘ্যের ইন্টারলিভ একাধিক তালিকাগুলি" এর শিরোনামের উত্তর দেওয়ার জন্য, আমরা @ekhumoro এর 2-তালিকা উত্তরকে সাধারণীকরণ করতে পারি। এটি সুস্পষ্টভাবে প্রয়োজন যে তালিকাগুলি একই দৈর্ঘ্য, @ এনপিইয়ের (মার্জিত) সমাধানের বিপরীতে
import itertools
def interleave(lists):
"""Interleave a list of lists.
:param lists: List of lists; each inner length must be the same length.
:returns: interleaved single list
:rtype: list
"""
if len(set(len(_) for _ in lists)) > 1:
raise ValueError("Lists are not all the same length!")
joint = list(itertools.chain(*lists))
for l_idx, li in enumerate(lists):
joint[l_idx::len(lists)] = li
return joint
উদাহরণ:
>>> interleave([[0,2,4], [1, 3, 5]])
[0, 1, 2, 3, 4, 5]
>>> interleave([[0,2,4], [1, 3, 5], [10, 11, 12]])
[0, 1, 10, 2, 3, 11, 4, 5, 12]
>>> interleave([[0,2,4], [1, 3, 5], [10, 11, 12], [13, 14, 15]])
[0, 1, 10, 13, 2, 3, 11, 14, 4, 5, 12, 15]
>>> interleave([[0,2,4], [1, 3, 5], [10, 11, 12], [13, 14]])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 10, in interleave
ValueError: Lists are not all the same length!
>>> interleave([[0,2,4]])
[0, 2, 4]
পার্টিতে দেরি হয়ে গেছে, এবং প্রচুর ভাল উত্তর রয়েছে তবে আমি extend()পদ্ধতিটি ব্যবহার করে একটি সহজ সমাধানও দিতে চাই :
list1 = [1, 2, 3]
list2 = [10, 20, 30]
new_list = []
for i in range(len(list1)):
new_list.extend([list1[i], list2[i]])
print(new_list)
আউটপুট:
[1, 10, 2, 20, 3, 30]
it = iter(l1); list((yield next(it)) or i for i in l2)