একটি তালিকায় প্রতি দুটি উপাদানকে ধরে নিয়ে যাওয়া


208

forপ্রতিটি পুনরুক্তি আমাকে দুটি উপাদান দেয় যাতে আমি কীভাবে একটি লুপ বা একটি তালিকা বোঝাপড়া করব?

l = [1,2,3,4,5,6]

for i,k in ???:
    print str(i), '+', str(k), '=', str(i+k)

আউটপুট:

1+2=3
3+4=7
5+6=11

2
: ওভারল্যাপিং যুগল জন্য stackoverflow.com/questions/5434891/...
user202729

উত্তর:


231

আপনার একটি 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

সমস্ত ক্রেডিট Martineau জন্য তার উত্তর করতে আমার প্রশ্ন , আমি এই পাওয়া যায় যেমন শুধুমাত্র তালিকা ধরে একবার iterates এবং প্রক্রিয়া যে কোন অপ্রয়োজনীয় তালিকা তৈরি করে না খুব দক্ষ হতে হবে।

এনবি : পাইথনের নিজস্ব ডকুমেন্টেশনের pairwiseরেসিপিটির সাথে এটি বিভ্রান্ত হওয়া উচিত নয় , যা ফল দেয় , মন্তব্যগুলিতে @ লাইজারের দ্বারা উল্লেখ করা হয়েছে ।itertoolss -> (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)

16
ইটারল্টুল রেসিপি বিভাগে প্রস্তাবিত জোড়ায়ু ফাংশন নিয়ে বিভ্রান্ত হওয়ার দরকার নেই , যা ফলন দেয়s -> (s0,s1), (s1,s2), (s2, s3), ...
লরিজ ভি ভি থালালো

1
এটি একটি ভিন্ন জিনিস করে। আপনার সংস্করণটি itertoolsএকই নামের সাথে রেসিপি ফাংশনটির তুলনায় জুটির অর্ধেক সংখ্যক ফল দেয় । অবশ্যই আপনারটি আরও দ্রুত ...
সোভেন মার্নাচ

তাই না? আপনার ফাংশন এবং ফাংশনটি আমি বিভিন্ন জিনিস করতে বলেছি এবং এটি ছিল আমার মন্তব্যের মূল বিষয়।
লরিৎজ ভি। থালো

5
সতর্ক হোন! এই ফাংশনগুলি ব্যবহার করে আপনাকে পুনরাবৃত্ত হওয়ার শেষ উপাদানগুলির সাথে পুনরাবৃত্তি না করার ঝুঁকি রাখে। উদাহরণ: তালিকা (দলবদ্ধ ([1,2,3], 2)) >>> [(1, 2)] .. আপনি যখন আশা করবেন [[(1,2), (3,)]
এফফনি

4
@ এরিক 49: প্রশ্নের ক্ষেত্রে সুনির্দিষ্ট ক্ষেত্রে, 'অসম্পূর্ণ' টিপল বুদ্ধিমান হবে না। আপনি যদি কোনও অসম্পূর্ণ টিপল অন্তর্ভুক্ত করতে চান তবে আপনি এর izip_longest()পরিবর্তে ব্যবহার করতে পারেন izip()। যেমন: list(izip_longest(*[iter([1, 2, 3])]*2, fillvalue=0))-> [(1, 2), (3, 0)]। আশাকরি এটা সাহায্য করবে.
জনসইয়েব

191

আচ্ছা আপনার 2 টি উপাদান রয়েছে, তাই need

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) এক্স এবং ওয়াই সংগ্রহগুলি একই সূচক উপাদানগুলি থেকে একটি দ্বৈত সংগ্রহ তৈরি করে।

8
দুটিরও বেশি উপাদানের প্রয়োজন হলে এটিও বাড়ানো যেতে পারে। উদাহরণস্বরূপfor i, j, k in zip(data[0::3], data[1::3], data[2::3]):
লাইফবালেন্স ২

19
কোনও আমদানি টানতে এবং কোনও ফাংশন সংজ্ঞায়িত করার চেয়ে আরও ক্লিনার!
কুমারশ

7
@ কেমার্শ: তবে এটি কেবল সিকোয়েন্সগুলিতে কাজ করে, ফাংশনটি কোনও পুনরাবৃত্তির উপরে কাজ করে; এবং এটি ও (এন) অতিরিক্ত স্থান ব্যবহার করে, ফাংশনটি করে না; অন্যদিকে, এটি সাধারণত দ্রুত হয়। একটি বা অন্যটি বেছে নেওয়ার ভাল কারণ রয়েছে; ভীত হওয়া importতাদের মধ্যে একটিও নয়।

77
>>> 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']

1
এটি পাইথন-৩. 3..০ তে কাজ করছে না তবে এখনও পাইথন-২.7.১০-তে কাজ করছে
হামিদ রোহানী

6
@ হামিদরোহানী পাইথন 3-তে zipএকটি zipবস্তু ফেরৎ দেয় যা সাবস্ক্রিপশনযোগ্য নয়। এটি প্রথমে একটি সিক্যুয়েন্সে ( list, tupleইত্যাদি) রূপান্তরিত হওয়া দরকার , তবে "কাজ না করা" কিছুটা প্রসারিত।
ভোল্টাহ

58

একটি সহজ সমাধান।

l = [1, 2, 3, 4, 5, 6]

আমার জন্য পরিসীমা (0, লেন (l), 2):
    মুদ্রণ (l [i]), '+', স্টার (l [আমি + 1]), '=', স্টার (এল [আমি] + ল [আমি + 1])

1
যদি আপনার তালিকাটি নাও হয় এবং আপনি কেবল সর্বশেষ নম্বরটি যেমন প্রদর্শন করতে চান তবে কী হবে?
হ্যান্স ডি জং

পছন্দ করেছেন দয়া করে আরও কিছুটা ব্যাখ্যা করুন।
টাস্কিনূর

2
ধন্যবাদ। এটি কীভাবে করা যায় তা আমি ইতিমধ্যে খুঁজে পেয়েছি। সমস্যাটি হ'ল যদি আপনার একটি তালিকা থাকে যা এতে সংখ্যার পরিমাণও না থাকে তবে এটি একটি সূচী ত্রুটি পেতে পারে। এটি একটি চেষ্টা করে সমাধান করুন: বাদে:
হান্স ডি জং

বা ((l[i], l[i+1])for i in range(0, len(l), 2))একটি জেনারেটরের জন্য, দীর্ঘ টিউপসগুলির জন্য সহজেই সংশোধন করা যায়।
বাসেল শিশানী

44

যদিও সমস্ত উত্তর ব্যবহার করে 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)

2
এই সমাধানটি
টিউপস

1
এই সমাধানটি যদি itকেবলমাত্র একজন পুনরুক্তি না হয় এবং পুনরাবৃত্ত হয় না তবে এটিও কাজ করে । অন্যান্য সমাধানগুলি ক্রমের জন্য দুটি স্বতন্ত্র পুনরুক্তি তৈরির সম্ভাবনার উপর নির্ভর করে বলে মনে হচ্ছে।
আকাশে আকাশ ছোঁয়া

এই উত্তরটি দেখার আগে আমি stackoverflow.com/a/16815056/2480481 এ এই পদ্ধতির সন্ধান পেয়েছি । জিপ () এর সাথে ডিল করার চেয়ে পরিষ্কার, সহজ।
এম 3 এন্ড

2
আমি এটি পছন্দ করি যে এটি গৃহীত উত্তর হিসাবে স্মৃতি ব্যবহারের ট্রিপল এড়াতে দেয়।
কেন্টজো

পিইপি 479 এরfor কারণে পাইথন 3.5+ এর লুপগুলির সাথে এটি ভালভাবে কাজ করে না , যা জেনারেটরে উত্থিত যেকোনোটিকে একটি দ্বারা প্রতিস্থাপন করে । StopIterationRuntimeError
সিডনি


18

আপনি যদি পারফরম্যান্সে আগ্রহী 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)]

12

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)]

10
for (i, k) in zip(l[::2], l[1::2]):
    print i, "+", k, "=", i+k

zip(*iterable) প্রতিটি পুনরাবৃত্তীয় পরবর্তী উপাদান সঙ্গে একটি tuple প্রদান।

l[::2] তালিকার 1 ম, তৃতীয়, 5 তম, ইত্যাদি উপাদান প্রদান করে: প্রথম কোলন সূচিত করে যে স্লাইসটি শুরুতে শুরু হয় কারণ এর পিছনে কোনও সংখ্যা নেই, দ্বিতীয় কোলন কেবল তখনই প্রয়োজন হয় যদি আপনি স্লাইসের একটি পদক্ষেপ চান '(এই ক্ষেত্রে 2)।

l[1::2]একই জিনিস আছে কিন্তু তালিকার দ্বিতীয় উপাদান মধ্যে শুরু হয়, তাই এটি 2nd, 4 র্থ, 6, ইত্যাদি উপাদান দেখায় মূল তালিকা।


4
এই উত্তরটি মার্গুস ইতিমধ্যে দু'বছর আগে দিয়েছিল। stackoverflow.com/questions/5389507/...
cababunga

1
[number::number]সিনট্যাক্স কীভাবে কাজ করে তা ব্যাখ্যা করার জন্য 1 । যারা প্রায়শই অজগর ব্যবহার করে না তাদের জন্য সহায়ক
অ্যালবাই

2

আনপ্যাকিং সহ:

l = [1,2,3,4,5,6]
while l:
    i, k, *l = l
    print(str(i), '+', str(k), '=', str(i+k))

কি দারুন! কেন আমি এই সম্পর্কে ভাবতে পারিনি :) আপনি যেখানে খাঁটি জুড়ি (বিজোড় এন্ট্রি) নেই কেবল সেখানে আপনাকে পরিচালনা করতে হবে
সৌরভ কুমার

1

এটি যে কারও পক্ষে সহায়তা করতে পারে, এখানে একই ধরণের সমস্যার সমাধান রয়েছে তবে ওভারল্যাপিং জোড়গুলি (পারস্পরিক একচেটিয়া জুটির পরিবর্তে)।

পাইথন ইটারটুলস ডকুমেন্টেশন থেকে :

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)


1

আমার একটি তালিকাটি একটি সংখ্যার দ্বারা বিভক্ত করতে হবে এবং এটি ঠিক করা উচিত।

l = [1,2,3,4,5,6]

def divideByN(data, n):
        return [data[i*n : (i+1)*n] for i in range(len(data)//n)]  

>>> print(divideByN(l,2))
[[1, 2], [3, 4], [5, 6]]

>>> print(divideByN(l,3))
[[1, 2, 3], [4, 5, 6]]

1

এটি করার অনেক উপায় আছে। উদাহরণ স্বরূপ:

lst = [1,2,3,4,5,6]
[(lst[i], lst[i+1]) for i,_ in enumerate(lst[:-1])]    
>>>[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]

[i for i in zip(*[iter(lst)]*2)]    
>>>[(1, 2), (3, 4), (5, 6)]

0

ভেবেছিলেন যে এটি আমার সাধারণকরণকে এন> ২ এর জন্য ভাগ করে নেওয়ার জন্য ভাল জায়গা, যা কেবল পুনরাবৃত্তির উপরে স্লাইডিং উইন্ডো:

def sliding_window(iterable, n):
    its = [ itertools.islice(iter, i, None) 
            for i, iter
            in enumerate(itertools.tee(iterable, n)) ]                               

    return itertools.izip(*its)

0

এই প্রশ্নের শিরোনাম বিভ্রান্তিমূলক, আপনি একটানা জোড়ের সন্ধান করছেন বলে মনে হচ্ছে, তবে আপনি যদি এর চেয়ে সমস্ত সম্ভাব্য জোড়ের সেটটি পুনরাবৃত্তি করতে চান তবে এটি কার্যকর হবে:

for i,v in enumerate(items[:-1]):
        for u in items[i+1:]:

0

টাইপিং ব্যবহার করে যাতে আপনি মাইপি স্ট্যাটিক বিশ্লেষণ সরঞ্জামটি ব্যবহার করে ডেটা যাচাই করতে পারেন :

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

0

একটি সরল পদ্ধতি:

[(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)]

(যদি আপনার অ্যারের দৈর্ঘ্য এবং ধাপটি ফিট না হয় তবে আপনাকে অতিরিক্ত মান সহ্য করতে হবে)


-1

এখানে আমাদের এমন 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)

দ্রষ্টব্য: উপরের সমাধানটি ফানক-এ সঞ্চালিত অপারেশনগুলি বিবেচনা করে দক্ষ নাও হতে পারে।


-1
a_list = [1,2,3,4,5,6]
empty_list = [] 
for i in range(0,len(a_list),2):
   empty_list.append(a_list[i]+a_list[i+1])   
print(empty_list)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.