जवाबों:
आपको एक pairwise()
(या grouped()
) कार्यान्वयन की आवश्यकता है।
पायथन 2 के लिए:
from itertools import izip
def pairwise(iterable):
"s -> (s0, s1), (s2, s3), (s4, s5), ..."
a = iter(iterable)
return izip(a, a)
for x, y in pairwise(l):
print "%d + %d = %d" % (x, y, x + y)
या, आम तौर पर:
from itertools import izip
def grouped(iterable, n):
"s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), (s2n,s2n+1,s2n+2,...s3n-1), ..."
return izip(*[iter(iterable)]*n)
for x, y in grouped(l, 2):
print "%d + %d = %d" % (x, y, x + y)
पायथन 3 में, आप izip
अंतर्निहित zip()
फ़ंक्शन के साथ प्रतिस्थापित कर सकते हैं और ड्रॉप कर सकते हैं import
।
करने के लिए सभी क्रेडिट मार्टिन्यू के लिए अपने जवाब के लिए मेरे सवाल है, मैं इस पाया है, क्योंकि यह केवल सूची पर एक बार iterates और इस प्रक्रिया में किसी भी अनावश्यक सूचियों का निर्माण नहीं करता बहुत ही कुशल होने के लिए।
नायब : यह अजगर के स्वयं के दस्तावेज में pairwise
नुस्खा के साथ भ्रमित नहीं होना चाहिए , जो पैदावार करता है , जैसा कि @lazyr द्वारा टिप्पणियों में बताया गया है ।itertools
s -> (s0, s1), (s1, s2), (s2, s3), ...
उन लोगों के लिए थोड़ा अतिरिक्त जो पायथन 3 पर मैपी के साथ टाइप चेकिंग करना चाहते हैं :
from typing import Iterable, Tuple, TypeVar
T = TypeVar("T")
def grouped(iterable: Iterable[T], n=2) -> Iterable[Tuple[T, ...]]:
"""s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), ..."""
return zip(*[iter(iterable)] * n)
s -> (s0,s1), (s1,s2), (s2, s3), ...
itertools
उसी नाम के साथ रेसिपी फ़ंक्शन की तुलना में जोड़े की आधी संख्या देता है । बेशक आपका तेज है ...
izip_longest()
इसके बजाय उपयोग कर सकते हैं izip()
। जैसे: list(izip_longest(*[iter([1, 2, 3])]*2, fillvalue=0))
-> [(1, 2), (3, 0)]
। उम्मीद है की यह मदद करेगा।
वैसे आपको 2 तत्वों का टपल चाहिए
data = [1,2,3,4,5,6]
for i,k in zip(data[0::2], data[1::2]):
print str(i), '+', str(k), '=', str(i+k)
कहाँ पे:
data[0::2]
का मतलब है कि तत्वों का सबसेट संग्रह बनाना (index % 2 == 0)
zip(x,y)
x और y समान अनुक्रमणिका तत्वों से टपल संग्रह बनाता है।for i, j, k in zip(data[0::3], data[1::3], data[2::3]):
import
उनमें से एक नहीं है।
>>> l = [1,2,3,4,5,6]
>>> zip(l,l[1:])
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
>>> zip(l,l[1:])[::2]
[(1, 2), (3, 4), (5, 6)]
>>> [a+b for a,b in zip(l,l[1:])[::2]]
[3, 7, 11]
>>> ["%d + %d = %d" % (a,b,a+b) for a,b in zip(l,l[1:])[::2]]
['1 + 2 = 3', '3 + 4 = 7', '5 + 6 = 11']
zip
एक zip
ऑब्जेक्ट देता है , जो सब्स्क्रिप्टेबल नहीं है। इसे पहले एक अनुक्रम ( list
और tuple
, आदि) में परिवर्तित करने की आवश्यकता है , लेकिन "काम नहीं करना" थोड़ा खिंचाव है।
एक सरल उपाय।
l = [१, २, ३, ४, ५, ६] मैं सीमा में (0, len (l), 2): प्रिंट str (l [i]), '+', str (l [i + 1]), '=', str (l [i] + l [i + 1])
((l[i], l[i+1])for i in range(0, len(l), 2))
जनरेटर के लिए, आसानी से लंबे समय तक ट्यूपल्स के लिए संशोधित किया जा सकता है।
हालांकि उपयोग करने वाले सभी उत्तर zip
सही हैं, मुझे लगता है कि कार्यक्षमता को लागू करने से खुद को अधिक पठनीय कोड की ओर जाता है:
def pairwise(it):
it = iter(it)
while True:
try:
yield next(it), next(it)
except StopIteration:
# no more elements in the iterator
return
it = iter(it)
हिस्सा सुनिश्चित है कि it
वास्तव में एक इटरेटर, न सिर्फ एक iterable है। यदि it
पहले से ही एक पुनरावृत्त है, तो यह पंक्ति एक सेशन नहीं है।
उपयोग:
for a, b in pairwise([0, 1, 2, 3, 4, 5]):
print(a + b)
it
केवल एक पुनरावृत्ति है और एक चलने योग्य नहीं है। अन्य समाधान अनुक्रम के लिए दो स्वतंत्र पुनरावृत्तियों को बनाने की संभावना पर भरोसा करते हैं।
for
कारण Python 3.5+ में छोरों के साथ अच्छी तरह से काम नहीं करता है , जो जनरेटर के साथ उठाए गए किसी भी स्थान को बदलता है । StopIteration
RuntimeError
मुझे उम्मीद है कि यह इसे करने का और भी सुंदर तरीका होगा।
a = [1,2,3,4,5,6]
zip(a[::2], a[1::2])
[(1, 2), (3, 4), (5, 6)]
यदि आप प्रदर्शन में रुचि रखते हैं, तो मैंने simple_benchmark
समाधानों के प्रदर्शन की तुलना करने के लिए एक छोटा बेंचमार्क (मेरी लाइब्रेरी का उपयोग ) किया और मैंने अपने पैकेज में से एक फ़ंक्शन शामिल किया:iteration_utilities.grouper
from iteration_utilities import grouper
import matplotlib as mpl
from simple_benchmark import BenchmarkBuilder
bench = BenchmarkBuilder()
@bench.add_function()
def Johnsyweb(l):
def pairwise(iterable):
"s -> (s0, s1), (s2, s3), (s4, s5), ..."
a = iter(iterable)
return zip(a, a)
for x, y in pairwise(l):
pass
@bench.add_function()
def Margus(data):
for i, k in zip(data[0::2], data[1::2]):
pass
@bench.add_function()
def pyanon(l):
list(zip(l,l[1:]))[::2]
@bench.add_function()
def taskinoor(l):
for i in range(0, len(l), 2):
l[i], l[i+1]
@bench.add_function()
def mic_e(it):
def pairwise(it):
it = iter(it)
while True:
try:
yield next(it), next(it)
except StopIteration:
return
for a, b in pairwise(it):
pass
@bench.add_function()
def MSeifert(it):
for item1, item2 in grouper(it, 2):
pass
bench.use_random_lists_as_arguments(sizes=[2**i for i in range(1, 20)])
benchmark_result = bench.run()
mpl.rcParams['figure.figsize'] = (8, 10)
benchmark_result.plot_both(relative_to=MSeifert)
इसलिए यदि आप बाहरी निर्भरता के बिना सबसे तेज़ समाधान चाहते हैं, तो आपको शायद जॉनीस्वेब द्वारा दिए गए दृष्टिकोण का उपयोग करना चाहिए (लेखन के समय यह सबसे उत्कीर्ण और स्वीकृत उत्तर है)।
आप अतिरिक्त निर्भरता कोई आपत्ति नहीं है तो grouper
से iteration_utilities
शायद थोड़ा तेजी से हो जाएगा।
कुछ दृष्टिकोणों में कुछ प्रतिबंध हैं, जिनकी चर्चा यहाँ नहीं की गई है।
उदाहरण के लिए कुछ समाधान केवल अनुक्रमों के लिए काम करते हैं (यानी सूची, तार आदि), उदाहरण के लिए मार्गस / प्यानोन / टास्किनोर समाधान, जो इंडेक्सिंग का उपयोग करता है, जबकि अन्य समाधान किसी भी चलने योग्य (जो अनुक्रम और जनरेटर, पुनरावृत्तियों) पर काम करते हैं , जैसे जॉनीस्वेब / mic_e / मेरे समाधान।
तब जॉनीस्वेब ने एक समाधान भी दिया जो अन्य आकारों के लिए 2 की तुलना में काम करता है जबकि अन्य उत्तर नहीं देते हैं (ठीक है, iteration_utilities.grouper
तत्वों की संख्या "समूह" पर सेट करने की भी अनुमति देता है)।
फिर यह भी सवाल है कि सूची में विषम संख्या में तत्व होने पर क्या होना चाहिए। क्या शेष वस्तु को खारिज कर दिया जाना चाहिए? क्या सूची को आकार देने के लिए पैड किया जाना चाहिए? क्या शेष वस्तु को एकल के रूप में लौटाया जाना चाहिए? अन्य उत्तर इस बिंदु को सीधे संबोधित नहीं करते हैं, हालांकि अगर मैंने कुछ भी अनदेखा नहीं किया है, तो वे सभी इस दृष्टिकोण का पालन करते हैं कि शेष आइटम को खारिज कर दिया जाना चाहिए (टास्किनर्स उत्तर को छोड़कर - जो वास्तव में अपवाद पैदा करेगा)।
साथ grouper
आप तय कर सकते हैं कि आप क्या करना चाहते हैं:
>>> from iteration_utilities import grouper
>>> list(grouper([1, 2, 3], 2)) # as single
[(1, 2), (3,)]
>>> list(grouper([1, 2, 3], 2, truncate=True)) # ignored
[(1, 2)]
>>> list(grouper([1, 2, 3], 2, fillvalue=None)) # padded
[(1, 2), (3, None)]
एक साथ कमांड zip
और प्रयोग करें iter
:
मुझे लगता है कि यह समाधान iter
काफी सुरुचिपूर्ण है:
it = iter(l)
list(zip(it, it))
# [(1, 2), (3, 4), (5, 6)]
जो मुझे पायथन 3 ज़िप प्रलेखन में मिला ।
it = iter(l)
print(*(f'{u} + {v} = {u+v}' for u, v in zip(it, it)), sep='\n')
# 1 + 2 = 3
# 3 + 4 = 7
# 5 + 6 = 11
N
एक समय में तत्वों को सामान्य करने के लिए :
N = 2
list(zip(*([iter(l)] * N)))
# [(1, 2), (3, 4), (5, 6)]
for (i, k) in zip(l[::2], l[1::2]):
print i, "+", k, "=", i+k
zip(*iterable)
प्रत्येक पुनरावृत्ति के अगले तत्व के साथ एक टपल देता है।
l[::2]
सूची का पहला, तीसरा, 5 वां इत्यादि तत्व देता है: पहला कोलन इंगित करता है कि स्लाइस शुरुआत में शुरू होता है क्योंकि इसके पीछे कोई संख्या नहीं होती है, दूसरे कोलन की जरूरत तभी होती है जब आप स्लाइस में 'स्टेप' चाहते हैं। '(इस मामले में 2)।
l[1::2]
एक ही बात करता है, लेकिन सूची के दूसरे तत्व में शुरू होता है इसलिए यह मूल सूची के 2, 4, 6, आदि तत्व को वापस करता है ।
[number::number]
वाक्य रचना कैसे काम करती है। जो अक्सर अजगर का उपयोग नहीं करता है के लिए मददगार
अनपैकिंग के साथ:
l = [1,2,3,4,5,6]
while l:
i, k, *l = l
print(str(i), '+', str(k), '=', str(i+k))
किसी के लिए भी यह मदद कर सकता है, यहां एक समान समस्या का समाधान है लेकिन अतिव्यापी जोड़े (पारस्परिक रूप से अनन्य जोड़े के बजाय)।
पायथन इटर्टूलस प्रलेखन से :
from itertools import izip
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return izip(a, b)
या, आम तौर पर:
from itertools import izip
def groupwise(iterable, n=2):
"s -> (s0,s1,...,sn-1), (s1,s2,...,sn), (s2,s3,...,sn+1), ..."
t = tee(iterable, n)
for i in range(1, n):
for j in range(0, i):
next(t[i], None)
return izip(*t)
आप more_itertools पैकेज का उपयोग कर सकते हैं ।
import more_itertools
lst = range(1, 7)
for i, j in more_itertools.chunked(lst, 2):
print(f'{i} + {j} = {i+j}')
टाइपिंग का उपयोग करके आप mypy स्थैतिक विश्लेषण उपकरण का उपयोग करके डेटा सत्यापित कर सकते हैं :
from typing import Iterator, Any, Iterable, TypeVar, Tuple
T_ = TypeVar('T_')
Pairs_Iter = Iterator[Tuple[T_, T_]]
def legs(iterable: Iterator[T_]) -> Pairs_Iter:
begin = next(iterable)
for end in iterable:
yield begin, end
begin = end
एक सरलीकृत दृष्टिकोण:
[(a[i],a[i+1]) for i in range(0,len(a),2)]
यह उपयोगी है यदि आपकी सरणी एक है और आप जोड़े द्वारा उस पर पुनरावृति करना चाहते हैं। उदाहरण के लिए, ट्रिपल या अधिक पर "श्रेणी" चरण कमांड को बदलने के लिए:
[(a[i],a[i+1],a[i+2]) for i in range(0,len(a),3)]
(यदि आपके सरणी की लंबाई और चरण फिट नहीं है, तो आपको अतिरिक्त मूल्यों से निपटना होगा)
यहां हमारे पास वह alt_elem
विधि हो सकती है जो आपके लूप के लिए फिट हो सकती है।
def alt_elem(list, index=2):
for i, elem in enumerate(list, start=1):
if not i % index:
yield tuple(list[i-index:i])
a = range(10)
for index in [2, 3, 4]:
print("With index: {0}".format(index))
for i in alt_elem(a, index):
print(i)
आउटपुट:
With index: 2
(0, 1)
(2, 3)
(4, 5)
(6, 7)
(8, 9)
With index: 3
(0, 1, 2)
(3, 4, 5)
(6, 7, 8)
With index: 4
(0, 1, 2, 3)
(4, 5, 6, 7)
नोट: ऊपर दिए गए समाधान कुशल नहीं हो सकते हैं, यह मानते हुए कि फंक में किए गए कार्यों पर विचार नहीं किया जाएगा।