पायथन में, क्या एक ही लंबाई की दो सूचियों को इंटरलेव करने का एक अच्छा तरीका है?
कहते हैं कि मैं दिया हूँ [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को Python2 के लिए और zip_longestpython3 `के लिए [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बिल्कुल सही लंबाई (इस स्तर पर, इसकी सामग्री महत्वपूर्ण नहीं हैं) की एक नई सूची बनाने के लिए एक सरल तरीके के रूप में लाइन का उपयोग किया जाता है। अगले दो पंक्तियों interleaving के वास्तविक कार्य करते हैं aऔर b: पहले एक के तत्वों प्रदान करती है aके सभी सम-संख्यांकित अनुक्रमित करने के लिए c; दूसरा bसभी विषम संख्याओं के तत्वों को निर्दिष्ट करता है c।
दिया हुआ
a = [1, 2, 3]
b = [10, 20, 30]
c = [100, 200, 300, 999]
कोड
मान लिया जाये कि समान लंबाई की सूची, आप के साथ एक interleaved सूची प्राप्त कर सकते हैं 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]
यह काम करता है क्योंकि मानचित्र समानांतर में सूचियों पर काम करता है। यह 2.2 के तहत समान काम करता है । अपने आप से, Noneतथाकथित कार्यों के साथ, mapटुपल्स की एक सूची तैयार करता है:
>>> map(None,l1,l2,'abcd')
[(1, 10, 'a'), (2, 20, 'b'), (3, 30, 'c'), (None, None, 'd')]
तो बस tuples की सूची समतल।
निश्चित रूप से, लाभ 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 y0भी बाहर फ़िल्टर करेगा , if y is not Noneकम नाजुक है।
मुझे ऐक्स का घोल सबसे अच्छा लगता है। यहाँ एक और तरीका है जो मुझे लगता है कि मुझे 2.2 में काम करना चाहिए:
>>> 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-सूची उत्तर को सामान्य कर सकते हैं। यह स्पष्ट रूप से आवश्यक है कि सूचियां @NPE द्वारा (सुरुचिपूर्ण) समाधान के विपरीत समान लंबाई हैं
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)