লুপ এবং আইএফ স্টেটমেন্টের একত্রিত করার পাইথোনিক উপায়


266

আমি জানি কিভাবে দুটি লুপের জন্য এবং কীভাবে পৃথক রেখায় বিবৃতি দেওয়া হয়:

>>> a = [2,3,4,5,6,7,8,9,0]
... xyz = [0,12,4,6,242,7,9]
... for x in xyz:
...     if x in a:
...         print(x)
0,4,6,7,9

এবং আমি জানি যে বিবৃতিগুলি সহজ হলে আমি এগুলি সংহত করতে একটি তালিকা বোধগম্যতা ব্যবহার করতে পারি, যেমন:

print([x for x in xyz if x in a])

তবে আমি যেটি খুঁজে পাচ্ছি না তা হ'ল কোথাও একটি দুর্দান্ত উদাহরণ (অনুলিপি করা এবং শিখতে) জটিল কমান্ডের প্রদর্শন করা (কেবল "প্রিন্ট x" নয়) যা লুপের জন্য একটি সংমিশ্রনের পরে ঘটে এবং কিছু বিবৃতি দেয়। এমন কিছু প্রত্যাশার মতো যা দেখতে প্রত্যাশা করব:

for x in xyz if x not in a:
    print(x...)

অজগরটি যেভাবে কাজ করবে বলে ঠিক তা নয়?


23
এটিই এরকম ... সরল করার চেষ্টা করে জিনিসগুলিকে অত্যধিক জটিল করবেন না। পাইথোনিকের অর্থ প্রতিটি স্পষ্ট forলুপ এবং ifবিবৃতি এড়ানো নয় does
ফেলিক্স ক্লিং

2
লুপের জন্য আপনার তালিকার বোধগম্যতার মধ্যে উত্পন্ন তালিকাটি আপনি ব্যবহার করতে পারেন। এটি আপনার শেষ উদাহরণের মতো দেখাবে।
ইয়াকুব

প্রসেসিংয়ে নামা, যদি একটি ইফ স্টেটমেন্টের সাথে লুপের জন্য একত্রিত করার দ্রুততম উপায় কী, যদি বিবৃতিটি ইতিমধ্যে মিলে যাওয়া মানগুলি বাদ দেয় এবং লুপটির পুনরাবৃত্তির জন্য তালিকার ক্রমবর্ধমান হয়?
ChewyChunks

3
@ ছাই, সঠিক ডেটা স্ট্রাকচারগুলি কোডটি দ্রুততর করবে, সিনট্যাকটিক চিনি নয়। উদাহরণস্বরূপ, x in aযদি aতালিকা হয় তবে ধীর হয়।
নিক ডানডৌলাকিস

1
এটি পাইথন, একটি অনুবাদিত ভাষা; কেন কেউ এত দ্রুত কোডটি নিয়ে আলোচনা করছেন?
আর্টঅফ ওয়ারফেয়ার

উত্তর:


323

আপনি এর মতো জেনারেটর এক্সপ্রেশন ব্যবহার করতে পারেন :

gen = (x for x in xyz if x not in a)

for x in gen:
    print x

1
gen = (y for (x,y) in enumerate(xyz) if x not in a)রিটার্ন >>> 12আমি যখন টাইপ করি for x in gen: print x- সুতরাং গণনার সাথে অপ্রত্যাশিত আচরণ কেন?
চেউইঙ্কস

9
সম্ভাব্য, তবে ব্লকগুলির জন্য এবং যদি এটি আসলটির চেয়ে ভাল নয়।
মাইক গ্রাহাম

1
@ChewyChunks। এটি কাজ করবে তবে গণনা করার কলটি অতিরিক্ত কাজ নয়।
জনসিওয়েব

132
for x in xyz if x:
অজগরটি

10
for x in (x for x in xyz if x not in a):আমার জন্য কাজ করে, তবে কেন আপনি কেবল সক্ষম হবেন না for x in xyz if x not in a:, আমি নিশ্চিত নই ...
ম্যাট ওয়েনহ্যাম

34

অনুযায়ী Python- র জেন (আপনি হতাশ হয় যদি কিনা আপনার কোড হল "Pythonic", যে যেতে জায়গা):

  • কদর্য চেয়ে সুন্দর।
  • সুস্পষ্ট বর্ণিত চেয়ে ভাল।
  • সহজ জটিল চেয়ে ভাল।
  • নেস্টেড থেকে ফ্ল্যাট ভাল।
  • পঠনযোগ্যতা গণনা।

দুটি এর দুটি পাওয়ার পাইথোনিক উপায় হ'ল:sorted intersectionset

>>> sorted(set(a).intersection(xyz))
[0, 4, 6, 7, 9]

বা যে উপাদানগুলি xyzকিন্তু এতে নেই a:

>>> sorted(set(xyz).difference(a))
[12, 242]

তবে আরও জটিল লুপের জন্য আপনি একটি নামী জেনারেটর এক্সপ্রেশনটি পুনরাবৃত্তি করে এবং / অথবা একটি নামযুক্ত ফাংশনটিতে কল করে এটি সমতল করতে চাইতে পারেন । এক লাইনে সবকিছু ফিট করার চেষ্টা খুব কমই "পাইথোনিক"।


আপনার প্রশ্ন এবং গৃহীত উত্তর সম্পর্কে অতিরিক্ত মন্তব্য নিম্নলিখিত আপডেট করুন

আপনি কী করতে চাইছেন তা আমি নিশ্চিত নই enumerate, তবে যদি aঅভিধান হয় তবে আপনি সম্ভবত কীগুলি ব্যবহার করতে চান:

>>> a = {
...     2: 'Turtle Doves',
...     3: 'French Hens',
...     4: 'Colly Birds',
...     5: 'Gold Rings',
...     6: 'Geese-a-Laying',
...     7: 'Swans-a-Swimming',
...     8: 'Maids-a-Milking',
...     9: 'Ladies Dancing',
...     0: 'Camel Books',
... }
>>>
>>> xyz = [0, 12, 4, 6, 242, 7, 9]
>>>
>>> known_things = sorted(set(a.iterkeys()).intersection(xyz))
>>> unknown_things = sorted(set(xyz).difference(a.iterkeys()))
>>>
>>> for thing in known_things:
...     print 'I know about', a[thing]
...
I know about Camel Books
I know about Colly Birds
I know about Geese-a-Laying
I know about Swans-a-Swimming
I know about Ladies Dancing
>>> print '...but...'
...but...
>>>
>>> for thing in unknown_things:
...     print "I don't know what happened on the {0}th day of Christmas".format(thing)
...
I don't know what happened on the 12th day of Christmas
I don't know what happened on the 242th day of Christmas

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

@ চাচিচংসস: জেনারেটরগুলি পাইথোনিক হওয়ার একমাত্র উপায় নয়!
জনসিওয়েব

3
@ জনসইয়েব, আপনি যদি পাইথনের জেনটি উদ্ধৃত করতে চলেছেন: "এখানে একটি হওয়া উচিত - এবং এটি করার একমাত্র উপায় - সম্ভবত উপায়"।
ওবল

@ উবল: সেখানে থাকা উচিত। আমি একই সময়ে আমার অন্য প্রশ্নের উত্তরে সেই বিভাগটি উদ্ধৃত করেছি !
জনসিওয়েব

18

আমি ব্যক্তিগতভাবে মনে করি এটি সর্বোপরি সংস্করণ:

a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]
for x in filter(lambda w: w in a, xyz):
  print x

সম্পাদন করা

আপনি যদি ল্যাম্বদা ব্যবহার এড়াতে খুব আগ্রহী হন তবে আপনি আংশিক ফাংশন অ্যাপ্লিকেশন ব্যবহার করতে পারেন এবং অপারেটর মডিউলটি ব্যবহার করতে পারেন (এটি বেশিরভাগ অপারেটরের ফাংশন সরবরাহ করে)।

https://docs.python.org/2/library/operator.html#module-operator

from operator import contains
from functools import partial
print(list(filter(partial(contains, a), xyz)))

4
filter(a.__contains__, xyz)। সাধারণত লোকেরা ল্যাম্বদা ব্যবহার করে, তখন তাদের সত্যিকারের আরও সহজ কিছু দরকার হয়।
ভেকি

আমি মনে করি আপনি কিছু ভুল বুঝেছেন। __contains__অন্যান্য পদ্ধতির মতো একটি পদ্ধতি, কেবল এটি একটি বিশেষ পদ্ধতি, যার অর্থ এটি অপারেটর দ্বারা অপ্রত্যক্ষভাবে বলা যেতে পারে ( inএই ক্ষেত্রে)। তবে এটি সরাসরি বলা যেতে পারে, এটি পাবলিক এপিআইয়ের একটি অংশ is বিশেষ পদ্ধতির নামগুলির জন্য ব্যতিক্রম প্রদানের জন্য ব্যক্তিগত নামগুলি নির্দিষ্টভাবে সর্বাধিক এক ট্রেলিং আন্ডারস্কোর হিসাবে সংজ্ঞায়িত করা হয় - এবং ক্লাস স্কোপে বর্ণিতভাবে যখন এগুলি নাম ম্যাঙ্গিলিংয়ের সাপেক্ষে থাকে। দেখুন docs.python.org/3/reference/datamodel.html#specialnames এবং docs.python.org/3.6/tutorial/classes.html#private-variables
ভিকি

এটি অবশ্যই ঠিক আছে, তবে কেবল দুটি বৈশিষ্ট্য ব্যবহার করে অ্যাক্সেসযোগ্য এমন কোনও পদ্ধতির উল্লেখ করতে সক্ষম হতে কেবল দুটি আমদানি অদ্ভুত বলে মনে হয় (ডাবল প্রেরণ যখন অপরিহার্য তখন অপারেটরগুলি সাধারণত ব্যবহৃত হয়, তবে inএককভাবে প্রসারিত আর্ট রাইট অপারেন্ড হয়)। এছাড়াও নোট করুন যে নামের অধীনেও পদ্ধতি operatorরফতানি containsকরে __contains__, তাই এটি অবশ্যই কোনও ব্যক্তিগত নাম নয়। আমি মনে করি আপনাকে কেবল এই সত্যটি নিয়ে বাঁচতে শিখতে হবে যে প্রতিটি ডাবল আন্ডারস্কোর মানে "দূরে থাক" না। : -]
ভিকি

আমি আপনার lambdaপ্রয়োজন অন্তর্ভুক্ত ফিক্সিং মনে করি not: lambda w: not w in a, xyz
জাভাদবা

ফিল্টারটি আরও মার্জিত বলে মনে হচ্ছে, বিশেষত জটিল অবস্থার জন্য যা ল্যাম্বডাসের পরিবর্তে সংজ্ঞায়িত ফাংশন হয়ে উঠবে, সম্ভবত ল্যাম্বডা ফাংশনটির নামকরণের ফলে কিছু পাঠযোগ্যতা যুক্ত হবে, জেনারেটরটি আরও ভাল মনে হয় যখন পুনরাবৃত্ত উপাদানগুলি তালিকার আইটেমগুলিতে কিছু সংশোধন করে
খানিস রক

16

নিম্নলিখিতটি গৃহীত উত্তর থেকে সরলীকরণ / একটি লাইনার:

a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]

for x in (x for x in xyz if x not in a):
    print(x)

12
242

লক্ষ করুন যে ইনলাইনgenerator রাখা হয়েছিল । এটি পরীক্ষা করা হয়েছিল এবং (পেরেন্টগুলিতে লক্ষ্য করুন ;))python2.7python3.6print


10

আমি সম্ভবত ব্যবহার করতে হবে:

for x in xyz: 
    if x not in a:
        print x...

@ কিরিলিটিটভ হ্যাঁ পাইথন একটি মৌলিকভাবে অ-কার্যকরী ভাষা (এটি খাঁটি অপরিহার্য কোডিং - এবং আমি এই উত্তরের লেখকের সাথে একমত হই যে পাইথনটি যেভাবে লেখার জন্য সেটআপ করা হয়েছে সেভাবেই। ফাংশনগুলি ব্যবহার করার চেষ্টা করা খারাপভাবে পড়তে বা অ- pythonicফলাফল। আমি যে সমস্ত ভাষা ব্যবহার করি সেগুলিতে আমি কার্যকরীভাবে কোড করতে পারি (স্ক্যালা, কোটলিন, জাভাস্ক্রিপ্ট, আর, সুইফ্ট, ..) তবে অজগরের মধ্যে কঠিন / বিশ্রী
জাভাদ্বা

9
a = [2,3,4,5,6,7,8,9,0]
xyz = [0,12,4,6,242,7,9]  
set(a) & set(xyz)  
set([0, 9, 4, 6, 7])

খুব জেন, @ লাজিয়ার, তবে আমাকে এমন জটিল কোড ব্লকটি উন্নত করতে সহায়তা করবে না যা একটি তালিকার মাধ্যমে পুনরাবৃত্তি করতে এবং অন্য তালিকার সাথে ম্যাচের উপাদানগুলি উপেক্ষা করার উপর নির্ভর করে। প্রথম তালিকাটিকে সেট হিসাবে বিবেচনা করা এবং ইউনিয়ন / পার্থক্যটিকে দ্বিতীয়, বর্ধমান "উপেক্ষা" তালিকার সাথে তুলনা করা কি দ্রুত?
চেউইঙ্কস

এটি ব্যবহার করে দেখুনimport time a = [2,3,4,5,6,7,8,9,0] xyz = [0,12,4,6,242,7,9] start = time.time() print (set(a) & set(xyz)) print time.time() - start
ক্রেসকুমার

@ চাচিচঙ্কস যদি পুনরাবৃত্তির সময় তালিকার কোনও একটির পরিবর্তন হয় তবে উপেক্ষা করা তালিকার বিরুদ্ধে প্রতিটি উপাদান চেক করা সম্ভবত দ্রুততর হবে - আপনি এটিকে একটি উপেক্ষা করা সেট বানানো ব্যতীত। সেটে সদস্যপদ জন্য চেক করা হচ্ছে খুব দ্রুত হল: if x in ignore: ...
লরিজ ভি ভি থালো

@ লাজিআর আমি একটি উপেক্ষা তালিকার উপরে উপেক্ষা সেট ব্যবহার করে কেবল আমার কোডটি আবার লিখেছি । সময়টি অনেক ধীর গতিতে দেখা যায়। (ন্যায্য বলতে আমি এটির সাথে তুলনা করছিলাম if set(a) - set(ignore) == set([]):তাই সম্ভবত এ কারণেই সদস্যতা যাচাই করার চেয়ে ধীর ছিল I'll ভবিষ্যতে আমি যা লিখছি তার থেকে আরও সহজ উদাহরণে এটি আবার পরীক্ষা করব
চেভিচঙ্কস

5

জেনারেটর এক্সপ্রেশনগুলি খুব জড়িত বা জটিল হয়ে উঠলে আপনি জেনারেটরগুলিও ব্যবহার করতে পারেন :

def gen():
    for x in xyz:
        if x in a:
            yield x

for x in gen():
    print x

এটি আমার কাছে আরও কিছুটা কার্যকর। আমি কখনও জেনারেটরের দিকে তাকাইনি। তারা ভীতিজনক শোনায় (কারণ আমি তাদের মডিউলগুলিতে দেখেছি যা সাধারণত ব্যবহারের জন্য ব্যথা হত)।
চিউইচিংস

2

ব্যবহার করুন intersectionবাintersection_update

  • ছেদ :

    a = [2,3,4,5,6,7,8,9,0]
    xyz = [0,12,4,6,242,7,9]
    ans = sorted(set(a).intersection(set(xyz)))
  • চৌরাস্তা_আপডেট :

    a = [2,3,4,5,6,7,8,9,0]
    xyz = [0,12,4,6,242,7,9]
    b = set(a)
    b.intersection_update(xyz)

    তাহলে bআপনার উত্তর


2

আমি অ্যালেক্সের উত্তরটি পছন্দ করেছি , কারণ একটি ফিল্টার যদি তালিকায় প্রয়োগ করা হয় তবে হ'ল আপনি যদি কোনও শর্তের সাথে তালিকার একটি উপসেটটি ঘুরে দেখতে চান তবে এটি সবচেয়ে প্রাকৃতিক উপায় বলে মনে হচ্ছে

mylist = [1,2,3,4,5]
another_list = [2,3,4]

wanted = lambda x:x in another_list

for x in filter(wanted, mylist):
    print(x)

এই পদ্ধতিটি উদ্বেগের পৃথককরণের জন্য দরকারী, যদি শর্তের ফাংশনটি পরিবর্তিত হয় তবে ফিডল করার একমাত্র কোডটি হ'ল ফাংশনটি

mylist = [1,2,3,4,5]

wanted = lambda x:(x**0.5) > 10**0.3

for x in filter(wanted, mylist):
    print(x)

জেনারেটরের যখন আপনি তালিকার সদস্যদের চাই না পদ্ধতি ভাল মনে হলেও বলেন সদস্যদের একটি পরিবর্তন, যা একটি আরো হইয়া বলে মনে হয় জেনারেটরের

mylist = [1,2,3,4,5]

wanted = lambda x:(x**0.5) > 10**0.3

generator = (x**0.5 for x in mylist if wanted(x))

for x in generator:
    print(x)

এছাড়াও, ফিল্টারগুলি জেনারেটরের সাথে কাজ করে, যদিও এই ক্ষেত্রে এটি দক্ষ নয়

mylist = [1,2,3,4,5]

wanted = lambda x:(x**0.5) > 10**0.3

generator = (x**0.9 for x in mylist)

for x in filter(wanted, generator):
    print(x)

তবে অবশ্যই এটি লিখতে ভাল লাগবে:

mylist = [1,2,3,4,5]

wanted = lambda x:(x**0.5) > 10**0.3

# for x in filter(wanted, mylist):
for x in mylist if wanted(x):
    print(x)

0

ক এবং বি তালিকাগুলির অনন্য সাধারণ উপাদানগুলি সন্ধান করার একটি সহজ উপায়:

a = [1,2,3]
b = [3,6,2]
for both in set(a) & set(b):
    print(both)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.