তাদের সূচকগুলি জেনে তালিকার একাধিক উপাদান অ্যাক্সেস করুন


232

আমাকে প্রদত্ত তালিকা থেকে তাদের সূচিগুলি জেনে কিছু উপাদান চয়ন করতে হবে। ধরা যাক আমি একটি নতুন তালিকা তৈরি করতে চাই, যার মধ্যে সূচিপত্র 1, 2, 5 দেওয়া আছে, [-2, 1, 5, 3, 8, 5, 6] থেকে উপাদান রয়েছে। আমি যা করেছি তা হ'ল:

a = [-2,1,5,3,8,5,6]
b = [1,2,5]
c = [ a[i] for i in b]

এটি করার আরও ভাল উপায় আছে কি? সি = এ [বি] এর মতো কিছু?


1
যাইহোক, আমি এখানে আরও একটি সমাধান খুঁজে পেয়েছি। আমি এটি এখনও পরীক্ষা করি নি, তবে আমি মনে করি আপনি একবার কোড.এ্যাকটিভস্টেট
ট্রান

প্রশ্নে উল্লিখিত একই সমাধান, তবে একটি lambdaকার্যক্রমে আবদ্ধ ।
উইল দেরহাম

উত্তর:


218

আপনি ব্যবহার করতে পারেন operator.itemgetter:

from operator import itemgetter 
a = [-2, 1, 5, 3, 8, 5, 6]
b = [1, 2, 5]
print(itemgetter(*b)(a))
# Result:
(1, 5, 5)

অথবা আপনি নকল ব্যবহার করতে পারেন :

import numpy as np
a = np.array([-2, 1, 5, 3, 8, 5, 6])
b = [1, 2, 5]
print(list(a[b]))
# Result:
[1, 5, 5]

তবে সত্যই, আপনার বর্তমান সমাধান ঠিক আছে। এটি সম্ভবত তাদের মধ্যে সবচেয়ে নিকটতম।


35
উল্লেখ করার জন্য +1 c = [a[i] for i in b]পুরোপুরি ঠিক আছে। দ্রষ্টব্য যে itemgetterবি তে 2 টিরও কম উপাদান রয়েছে তবে দ্রবণটি একই জিনিসটি করবে না।
ফ্লোরকোয়েন

পার্শ্ব দ্রষ্টব্য : মাল্টি-প্রসেসে কাজ করার সময় আইটেমজিটার ব্যবহার করা কার্যকর হয় না। নম্পি মাল্টি-প্রসেসে দুর্দান্ত কাজ করে।
লিওর ম্যাগেন

3
অতিরিক্ত মন্তব্য, কেবল তখনই a[b]কাজ করে যখন একটি নমপি অ্যারে থাকে, অর্থাত আপনি এটিকে একটি নিম্পী ফাংশন দিয়ে তৈরি করেন। a
লুডভিগ চিউ

আমি অ numpy অপশন benchmarked এবং itemgetter, দ্রুততম হতে সামান্য দ্রুততর হচ্ছে কেবল বাইরে প্রথম বন্ধনী ভিতরে পছন্দসই ইনডেক্স, টাইপ ব্যবহার পাইথন 3.44 চেয়ে
ragardner

@ Citizens2077, আপনি বর্ণনা করেছেন এমন সিনট্যাক্সের উদাহরণ দিতে পারেন?
আলঙ্কালভিটি

47

বিকল্প:

>>> map(a.__getitem__, b)
[1, 5, 5]

>>> import operator
>>> operator.itemgetter(*b)(a)
(1, 5, 5)

প্রথমটি চমৎকার কারণ আপনি build-inফাংশন ব্যবহার করেন
সিলগন

__getitem__ডাব্লু / প্রথমটি সমস্যাটি তুলনামূলক বলে মনে হয় না যেমন আইটেমের ধরণটি কীভাবে মানচিত্র করা যায়? map(type(a.__getitem__), b)
অ্যালাঙ্কলভিটি

@ আলাঙ্কালভিটি lambda x: type(a.__getitem__(x)), b,। [..]lambda x: type(a[x]), b
এক্ষেত্রে

9

আর একটি সমাধান পান্ডাস সিরিজের মাধ্যমে হতে পারে:

import pandas as pd

a = pd.Series([-2, 1, 5, 3, 8, 5, 6])
b = [1, 2, 5]
c = a[b]

আপনি চাইলে আপনি সিটিকে আবার তালিকায় রূপান্তর করতে পারেন:

c = list(c)

7

সরবরাহিত পাঁচটি উত্তরের কার্য সম্পাদনের সময়ের সাথে তুলনা করে মৌলিক এবং খুব বিস্তৃত পরীক্ষা নয়:

def numpyIndexValues(a, b):
    na = np.array(a)
    nb = np.array(b)
    out = list(na[nb])
    return out

def mapIndexValues(a, b):
    out = map(a.__getitem__, b)
    return list(out)

def getIndexValues(a, b):
    out = operator.itemgetter(*b)(a)
    return out

def pythonLoopOverlap(a, b):
    c = [ a[i] for i in b]
    return c

multipleListItemValues = lambda searchList, ind: [searchList[i] for i in ind]

নিম্নলিখিত ইনপুট ব্যবহার:

a = range(0, 10000000)
b = range(500, 500000)

ল্যাম্বডা অপারেশনের সাথে সহজ পাইথন লুপটি ছিল দ্রুততম দ্বিতীয়, ম্যাপআইডেক্সভ্যালিউস এবং getIndexValues ​​নাম্বার পদ্ধতিতে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে মিলিয়ে যায়। দ্রুততম।

numpyIndexValues -> time:1.38940598 (when converted the lists to numpy arrays)
numpyIndexValues -> time:0.0193445 (using numpy array instead of python list as input, and conversion code removed)
mapIndexValues -> time:0.06477512099999999
getIndexValues -> time:0.06391049500000001
multipleListItemValues -> time:0.043773591
pythonLoopOverlap -> time:0.043021754999999995

আমি কি পাইথন জানি না ব্যাখ্যাকারী আপনি ব্যবহার কিন্তু প্রথম পদ্ধতি numpyIndexValuesকাজ করে না যেহেতু a, bধরনের range। আমি অনুমান করছি যে আপনার রূপান্তর করতে ment a, bকরতে numpy.ndarraysপ্রথম?
strpeter

@স্ট্রপেটার হ্যাঁ আমি আপেলের সাথে আপেলের তুলনা করছিলাম না, আমি নম্পিআইন্ডেক্সভ্যালুগুলির পরীক্ষার ক্ষেত্রে ইনপুট হিসাবে নম্পটি অ্যারে তৈরি করেছিলাম। আমি এটি এখনই ঠিক করে রেখেছি এবং সমস্ত ইনপুট হিসাবে একই তালিকা ব্যবহার করে।
ডন স্মিথ

4

আমি নিশ্চিত যে এটি ইতিমধ্যে বিবেচিত হয়েছে: খ-তে সূচকের পরিমাণ যদি সামান্য এবং ধ্রুবক হয় তবে কেউ কেবল ফলাফল লিখতে পারে:

c = [a[b[0]]] + [a[b[1]]] + [a[b[2]]]

বা সূচকগুলি যদি স্থির হয় তবে আরও সহজ ...

c = [a[1]] + [a[2]] + [a[5]]

বা যদি ধারাবাহিক পরিসীমা সূচকগুলি থাকে ...

c = a[1:3] + [a[5]]

আমাকে মনে করিয়ে দেওয়ার জন্য আপনাকে ধন্যবাদ[a] + [b] = [a, b]
'23:57 এ একত্রীয়েড


1

আমার উত্তরটি নপী বা পাইথন সংগ্রহগুলি ব্যবহার করে না।

উপাদানগুলি খুঁজে পাওয়ার একটি তুচ্ছ উপায় নিম্নরূপ হবে:

a = [-2, 1, 5, 3, 8, 5, 6]
b = [1, 2, 5]
c = [i for i in a if i in b]

খসড়া: এই পদ্ধতিটি বৃহত তালিকার জন্য কাজ নাও করতে পারে। বৃহত্তর তালিকার জন্য নিম্পি ব্যবহারের পরামর্শ দেওয়া হচ্ছে।


5
পুনরাবৃত্তি করার দরকার নেই a[a[i] for i in b]
ফলসেট্রু

1
এই পদ্ধতিটি অন্য কোনও ক্ষেত্রেও কাজ করে না। এর aমধ্যে আরও ৫ টি থাকলে কী হবে?
টেরি


আপনি যদি সূচকের ভুল সম্পর্কে উদ্বিগ্ন হন যদি বি এর আকার এর চেয়ে বেশি নম্বর থাকে তবে চেষ্টা করুন[a[i] if i<len(a) else None for i in b]
576i

0

স্ট্যাটিক ইনডেক্স এবং ছোট তালিকা?

ভুলে যাবেন না যে যদি তালিকাটি ছোট হয় এবং সূচকগুলি পরিবর্তন না হয়, যেমন আপনার উদাহরণ হিসাবে, কখনও কখনও সিক্যুয়েন্সটি আনপ্যাকিং না করা সর্বোত্তম জিনিস :

_,a1,a2,_,_,a3,_ = a

পারফরম্যান্সটি আরও ভাল এবং আপনি কোডের একটি লাইনও সংরক্ষণ করতে পারেন:

 %timeit _,a1,b1,_,_,c1,_ = a
10000000 loops, best of 3: 154 ns per loop 
%timeit itemgetter(*b)(a)
1000000 loops, best of 3: 753 ns per loop
 %timeit [ a[i] for i in b]
1000000 loops, best of 3: 777 ns per loop
 %timeit map(a.__getitem__, b)
1000000 loops, best of 3: 1.42 µs per loop

0

পাইথোনিক উপায়ে

c = [x for x in a if a.index(x) in b]

2
আমি এটি ওপি-র উদাহরণের চেয়ে কম "পাইথোনিক" বলব - আপনি কোডটির দৈর্ঘ্য প্রায় দ্বিগুণ করার সময় আপনি তাদের O(n)সমাধানটিকে একটি O(n^2)সমাধানে পরিণত করতে পেরেছেন । আপনি নোট করতে চাইবেন যে তালিকাটি যদি বস্তুগুলিকে অস্পষ্ট বা আংশিক সাম্যতা aধারণ করে float('nan'), উদাহরণস্বরূপ ব্যর্থ হবে, উদাহরণস্বরূপ , এটি সর্বদা একটি বাড়িয়ে তুলবে ValueError
ব্রায়ান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.