একটি তালিকা বা tuple থেকে স্পষ্টভাবে আইটেম নির্বাচন করুন


120

আমার নীচের পাইথন তালিকা রয়েছে (এটি একটি টিপলও হতে পারে):

myList = ['foo', 'bar', 'baz', 'quux']

আমি বলতে পারি

>>> myList[0:3]
['foo', 'bar', 'baz']
>>> myList[::2]
['foo', 'baz']
>>> myList[1::2]
['bar', 'quux']

যার সূচকগুলির নির্দিষ্ট কোনও নিদর্শন নেই সেগুলি আমি কীভাবে স্পষ্টভাবে বাছাই করব? উদাহরণস্বরূপ, আমি নির্বাচন করতে চাই [0,2,3]। বা 1000 আইটেমগুলির একটি খুব বড় তালিকা থেকে, আমি নির্বাচন করতে চাই [87, 342, 217, 998, 500]। কিছু পাইথন সিনট্যাক্স আছে যে এটি করে? দেখে মনে হচ্ছে এমন কিছু:

>>> myBigList[87, 342, 217, 998, 500]

1
এটি একটি সদৃশ বলে মনে হচ্ছে। অন্য প্রশ্নের বেশি ভোট রয়েছে তবে সময়সীমার সাথে এর আরও ভাল উত্তর রয়েছে বলে মনে হয়।
আনানফায়

উত্তর:


149
list( myBigList[i] for i in [87, 342, 217, 998, 500] )

আমি উত্তরগুলি অজগর 2.5.2 এর সাথে তুলনা করেছি:

  • 19.7 ইউএসসি: [ myBigList[i] for i in [87, 342, 217, 998, 500] ]

  • 20.6 ইউএসসি: map(myBigList.__getitem__, (87, 342, 217, 998, 500))

  • 22.7 ইউএসসি: itemgetter(87, 342, 217, 998, 500)(myBigList)

  • 24.6 ইউএসসি: list( myBigList[i] for i in [87, 342, 217, 998, 500] )

দ্রষ্টব্য যে পাইথন 3-এ, 1 মটিকে 4 র্থ হিসাবে একই হিসাবে পরিবর্তন করা হয়েছিল।


আরেকটি বিকল্প numpy.arrayহ'ল একটি তালিকা দিয়ে শুরু করা যা কোনও তালিকা বা এর মাধ্যমে সূচকে অনুমতি দেয় numpy.array:

>>> import numpy
>>> myBigList = numpy.array(range(1000))
>>> myBigList[(87, 342, 217, 998, 500)]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: invalid index
>>> myBigList[[87, 342, 217, 998, 500]]
array([ 87, 342, 217, 998, 500])
>>> myBigList[numpy.array([87, 342, 217, 998, 500])]
array([ 87, 342, 217, 998, 500])

tupleযারা টুকরা একই ভাবে কাজ করে না।


2
সাধারণত একটি তালিকা কমপ হিসাবে [myBigList[i] for i in [87, 342, 217, 998, 500]], তবে আমি এই পদ্ধতির সেরা পছন্দ করি।
zeekay

@ মেঘাটহেলমি এটি ইতিমধ্যে উত্তরে। from operator import itemgetterএর সূচনা অংশে ব্যবহৃত তৃতীয় বিকল্প python -mtimeit
ড্যান ডি

আমি ভাবছি, কেবল একটি ভাষা নকশার দৃষ্টিকোণ থেকে, নিয়মিত অজগর myBigList[(87, 342, 217, 998, 500)]হলে কেন কাজ করে না ? যখন আমি চেষ্টা করি যে আমি পেয়েছি । এটি উপলব্ধিটি টাইপ করার চেয়ে অনেক সহজ হবে - কোনও ভাষা নকশা / বাস্তবায়ন সমস্যা জড়িত আছে? myBigListlistTypeError: list indices must be integers or slices, not tuple
স্পার্ক_স্প্রেড

@ স্পার_স্প্রেড, এটি কারণ listsপাইথনে কেবলমাত্র পূর্ণসংখ্যা বা স্লাইস গ্রহণ করা হয়। পূর্ণসংখ্যা পাস করা নিশ্চিত করে যে বিদ্যমান তালিকা থেকে কেবলমাত্র একটি আইটেম উদ্ধার করা হয়েছে। একটি স্লাইস পাস করা নিশ্চিত করে তোলে যে এর একটি অংশ পুনরুদ্ধার করা হয়েছে, তবে একটি টুপল পাস tupleকরা অন্য ডেটা-টাইপ ( list) -র সাথে যুক্তি হিসাবে একটি ডেটা-টাইপ ( ) কে পাস করার মতো যা সিনথেটিকভাবে ভুল।
আমানব

48

এই সম্পর্কে কি:

from operator import itemgetter
itemgetter(0,2,3)(myList)
('foo', 'baz', 'quux')

2
এটি এখন পর্যন্ত যৌনতম। যে operatorমডিউল প্রেম !
jathanism

10

এটি অন্তর্নির্মিত নয়, তবে আপনি চাইলে তালিকার একটি সাবক্লাস তৈরি করতে পারেন যা "ইন্ডেক্স" হিসাবে গৃহীত হয়:

class MyList(list):

    def __getitem__(self, index):
        if isinstance(index, tuple):
            return [self[i] for i in index]
        return super(MyList, self).__getitem__(index)


seq = MyList("foo bar baaz quux mumble".split())
print seq[0]
print seq[2,4]
print seq[1::2]

মুদ্রণ

foo
['baaz', 'mumble']
['bar', 'quux']

2
(+1) ঝরঝরে সমাধান! এই এক্সটেনশনটির সাথে পাইথনে অ্যারে পরিচালনা করা অনেকগুলি আর বা মতলব দেখতে শুরু করে।
আসাদ ইব্রাহিম

7

সম্ভবত একটি তালিকা বোধগম্য ক্রমযুক্ত:

L = ['a', 'b', 'c', 'd', 'e', 'f']
print [ L[index] for index in [1,3,5] ]

উত্পাদন:

['b', 'd', 'f']

যে আপনার জন্য খুঁজছেন?


6
>>> map(myList.__getitem__, (2,2,1,3))
('baz', 'baz', 'bar', 'quux')

আপনি নিজের Listশ্রেণি তৈরি করতে __getitem__পারেন যা আপনি করতে সক্ষম হতে চাইলে যুক্তি হিসাবে টিপলসকে সমর্থন করে myList[(2,2,1,3)]


এটি যখন কাজ করে তখন সাধারণত যাদু ভেরিয়েবলগুলি সরাসরি ডাকা ভাল ধারণা নয়। আপনি কোনও তালিকা বোঝার বা কোনও সহায়ক মডিউল ব্যবহার করে আরও ভাল operator
jathanism

@ জাথানিজম: আমাকে শ্রদ্ধার সাথে একমত হতে হবে না। আপনি যদি সামনের সামঞ্জস্যের বিষয়ে উদ্বিগ্ন হন (সরকারী / ব্যক্তিগত বিপরীতে) আমি অবশ্যই দেখতে পাচ্ছি আপনি কোথা থেকে এসেছেন।
নিনজাগেকো

সেখান থেকেই আসছি। :) যে নিম্নলিখিত, এটি একই কারণে এটি ব্যবহার করতে ভালো এর len(myList)উপর myList.__len__()
jathanism

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

2

আমি কেবল উল্লেখ করতে চাই, এমনকি আইটেমজিটারের বাক্য গঠনটিও খুব ঝরঝরে দেখায়, তবে বড় তালিকায় সম্পাদন করার সময় ধীর গতিতে ধীরস্থির হয়।

import timeit
from operator import itemgetter
start=timeit.default_timer()
for i in range(1000000):
    itemgetter(0,2,3)(myList)
print ("Itemgetter took ", (timeit.default_timer()-start))

আইটেমজিটার 1.065209062149279 নিয়েছে

start=timeit.default_timer()
for i in range(1000000):
    myList[0],myList[2],myList[3]
print ("Multiple slice took ", (timeit.default_timer()-start))

একাধিক স্লাইস 0.6225321444745759 নিয়েছে


প্রথম স্নিপেট, দয়া করে যুক্ত করুন myList = np.array(range(1000000))অন্যথায় আপনি ত্রুটি পাবেন।
মেঘ চো

1

আর একটি সম্ভাব্য সমাধান:

sek=[]
L=[1,2,3,4,5,6,7,8,9,0]
for i in [2, 4, 7, 0, 3]:
   a=[L[i]]
   sek=sek+a
print (sek)

0

প্রায়শই যখন আপনি বুলিয়ান নাম্পার অ্যারে পছন্দ করেন mask

[mylist[i] for i in np.arange(len(mask), dtype=int)[mask]]

যে ল্যাম্বদা কোনও অনুক্রম বা এনপি.আরয়ের জন্য কাজ করে:

subseq = lambda myseq, mask : [myseq[i] for i in np.arange(len(mask), dtype=int)[mask]]

newseq = subseq(myseq, mask)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.