পাইথন: সূচিপত্রের ভিত্তিতে তালিকা থেকে উপসেটটি নির্বাচন করুন


99

আমার কাছে বেশ কয়েকটি তালিকা রয়েছে যাতে একই সংখ্যক এন্ট্রি রয়েছে (প্রতিটি বস্তুর সম্পত্তি নির্দিষ্ট করে):

property_a = [545., 656., 5.4, 33.]
property_b = [ 1.2,  1.3, 2.3, 0.3]
...

এবং একই দৈর্ঘ্যের পতাকা সহ তালিকান

good_objects = [True, False, False, True]

(যা সহজেই একটি সমতুল্য সূচক তালিকার সাথে প্রতিস্থাপিত হতে পারে:

good_indices = [0, 3]

সবচেয়ে সহজ উপায় নতুন তালিকাগুলিতে জেনারেট করতে কি property_asel, property_bsel... যা ধারণ করে শুধুমাত্র মান দ্বারা পারেন নির্দেশিত Trueএন্ট্রি বা সূচকের?

property_asel = [545., 33.]
property_bsel = [ 1.2, 0.3]

উত্তর:


128

আপনি কেবল তালিকা বোধগম্যতা ব্যবহার করতে পারেন :

property_asel = [val for is_good, val in zip(good_objects, property_a) if is_good]

বা

property_asel = [property_a[i] for i in good_indices]

পরেরটিটি দ্রুততর কারণ এখানে good_indicesদৈর্ঘ্যের চেয়ে কম রয়েছে বলে property_aধরে নেওয়া যায় good_indicesযে ফ্লাইটটি অন-ফ্লাইয়ের পরিবর্তে প্রম্পট করা হবে।


সম্পাদনা করুন : itertools.compressপাইথন ২.7 / ৩.১ থেকে প্রথম বিকল্পটি সমান । দেখুন @Gary কের এর উত্তর।

property_asel = list(itertools.compress(property_a, good_objects))

4
@ ফুয়েন: হ্যাঁ পাইথন ২-তে প্রচুর কারণ ঘটায় (এর পরিবর্তে itertools.izip ব্যবহার করুন), পাইথন ৩-তে খুব বেশি নয় এটি কারণ এটি zipপাইথন ২-এ একটি নতুন তালিকা তৈরি করবে, কিন্তু পাইথন 3 এ এটি কেবল একটি (অলস) জেনারেটর ফিরিয়ে আনবে।
কেনেটিএম

ঠিক আছে, সুতরাং আমার তখন আপনার দ্বিতীয় প্রস্তাবটি আটকে রাখা উচিত, কারণ এটি আমার কোডের কেন্দ্রীয় অংশটি তৈরি করে।
fuenfundachtzig

4
@ 85: আপনি পারফরম্যান্স নিয়ে কেন চিন্তিত? আপনার যা করতে হবে তা লিখুন, যদি এটি ধীর হয় তবে বাধা খুঁজে পেতে পরীক্ষা করুন।
গ্যারি কেরেল

4
@ প্রিলেডএন্ডফিউগু: যদি দুটি সমতুল্য বিকল্প থাকে তবে কোনটি দ্রুত তা জানা ভাল এবং এটি এখনই ব্যবহার করুন use
fuenfundachtzig

4
আপনি প্রথম উদাহরণটির from itertools import izipপরিবর্তে কেবল এটি ব্যবহার ও ব্যবহার করতে পারেন zip। পাইথন 3 এর মতো একটি পুনরাবৃত্তি তৈরি করে
ক্রিস বি

28

আমি 2 টি বিকল্প দেখছি।

  1. অদ্ভুত ব্যবহার:

    property_a = numpy.array([545., 656., 5.4, 33.])
    property_b = numpy.array([ 1.2,  1.3, 2.3, 0.3])
    good_objects = [True, False, False, True]
    good_indices = [0, 3]
    property_asel = property_a[good_objects]
    property_bsel = property_b[good_indices]
    
  2. একটি তালিকা বোধগম্যতা ব্যবহার করে এটি জিপ করুন:

    property_a = [545., 656., 5.4, 33.]
    property_b = [ 1.2,  1.3, 2.3, 0.3]
    good_objects = [True, False, False, True]
    good_indices = [0, 3]
    property_asel = [x for x, y in zip(property_a, good_objects) if y]
    property_bsel = [property_b[i] for i in good_indices]
    

4
ওপি তালিকাগুলিতে সংখ্যা সংরক্ষণ করতে চায় বলে মনে হয় নিম্পি ব্যবহার করা ভাল পরামর্শ। একটি দ্বিমাত্রিক অ্যারে আরও ভাল হবে।
ফিলিপ

এটিও একটি ভাল পরামর্শ কারণ এটি আর এর ব্যবহারকারীদের কাছে খুব পরিচিত সিনট্যাক্স হবে, যেখানে এই ধরণের নির্বাচন খুব শক্তিশালী, বিশেষত যখন নেস্টেড এবং / বা বহুমাত্রিক হয়।
টমাস ব্রাউন 21

4
[property_b[i] for i in good_indices]ছাড়া ব্যবহার করার জন্য একটি ভাল একnumpy
ইলিয়া Rusin

15

বিল্ট ইন ফাংশন জিপ ব্যবহার করুন

property_asel = [a for (a, truth) in zip(property_a, good_objects) if truth]

সম্পাদনা

মাত্র 2.7 এর নতুন বৈশিষ্ট্যগুলি দেখছি। ইটারটুলস মডিউলে এখন একটি ফাংশন রয়েছে যা উপরের কোডের মতো।

http://docs.python.org/library/itertools.html#itertools.compress

itertools.compress('ABCDEF', [1,0,1,0,1,1]) =>
  A, C, E, F

4
আমি itertools.compressএখানে ব্যবহার করে আচ্ছন্ন । হ্যাক কম্প্রেস কী করছে তা খনন না করে তালিকার বোঝাপড়াটি আরও বেশি পঠনযোগ্য।
PaulMcG

4
এইচএম, আমি কোডটি সংক্ষেপে আরও বেশি পাঠযোগ্য find
ফুয়েনফুন্ডাচটজিগ

আপনি itertools.compressডকুমেন্টেশনের উদাহরণ কপি করার পরিবর্তে একটি উদাহরণ সরবরাহ করবেন না কেন ?
নিকোলাস গ্রাভেইস

8

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

property_asel = [ property_a[index] for index in good_indices ]

এর অর্থ প্রকৃত / প্রয়োজনীয় সূচকগুলি হিসাবে সম্পত্তি নির্বাচন কেবলমাত্র বহু রাউন্ডে কাজ করবে। যদি আপনার কাছে প্রচুর সম্পত্তি তালিকাগুলি থাকে যা কোনও একক ট্যাগের (যথাযথ / মিথ্যা) তালিকার নিয়ম অনুসরণ করে তবে আপনি একই তালিকা অনুধাবন নীতিগুলি ব্যবহার করে একটি সূচক তালিকা তৈরি করতে পারেন:

good_indices = [ index for index, item in enumerate(good_objects) if item ]

এটি গুড_বজেক্টসগুলিতে প্রতিটি আইটেমের মাধ্যমে পুনরাবৃত্তি করে (যখন সূচকটি গণনার সাথে স্মরণ করে) এবং কেবলমাত্র সেই সূচকগুলিতে ফিরে আসে যেখানে আইটেমটি সত্য।


যে কেউ তালিকার বোধগম্যতা পাচ্ছেন না, তার জন্য এখানে একটি ইংরেজী গদ্য সংস্করণ রয়েছে কোডটি গা bold়ভাবে হাইলাইট করা হয়েছে:

তালিকা প্রস্তুত জন্য সূচক প্রতিটি গ্রুপ সূচক, আইটেম যে বিদ্যমান মধ্যে একটি শুমার এর ভাল বস্তু , যদি (যেখানে) আইটেমটি সত্য


-1

মাতলাব এবং সাইলেব ভাষাগুলি আপনি যে প্রশ্ন জিজ্ঞাসা করছেন তার জন্য পাইথনের চেয়ে সহজ এবং আরও মার্জিত সিনট্যাক্স সরবরাহ করে, তাই আমি মনে করি যে পাইথনের নম্পি প্যাকেজটি ব্যবহার করে মতলব / সাইলেবকে অনুকরণ করা আপনি সবচেয়ে ভাল। এটি করে আপনার সমস্যার সমাধানটি খুব সংক্ষিপ্ত এবং মার্জিত:

from numpy import *
property_a = array([545., 656., 5.4, 33.])
property_b = array([ 1.2,  1.3, 2.3, 0.3])
good_objects = [True, False, False, True]
good_indices = [0, 3]
property_asel = property_a[good_objects]
property_bsel = property_b[good_indices]

নম্পি মাতলাব / সাইল্যাবকে অনুকরণ করার চেষ্টা করে তবে এটি ব্যয় করে: আপনাকে "অ্যারে" মূল শব্দটি দিয়ে প্রতিটি তালিকা ঘোষণা করতে হবে যা আপনার স্ক্রিপ্টকে ওভারলোড করবে (মতলব / সায়্লাবের সাথে এই সমস্যাটি নেই)। নোট করুন যে এই সমাধানটি সংখ্যার অ্যারেগুলিতে সীমাবদ্ধ রয়েছে, এটি আপনার উদাহরণের ক্ষেত্রে।


4
প্রশ্নে কোথাও তিনি নমপির কথা উল্লেখ করেননি - নম্পপি বনাম মতলব সম্পর্কে আপনার মতামত প্রকাশ করার দরকার নেই। পাইথন তালিকাগুলি NumPy অ্যারেগুলির মতো একই জিনিস নয় , এমনকি যদি তারা উভয়ই ভেক্টরগুলির সাথে মোটামুটি মিল থাকে। (পাইথন তালিকাগুলি মতলব সেল অ্যারেগুলির মতো - প্রতিটি উপাদানটিতে আলাদা আলাদা ডেটা ধরণের থাকতে পারে certain পাইথনের অন্তর্নির্মিত filterবা বাহ্যিক গ্রন্থাগারের মাধ্যমে আপনি আপনার উদাহরণের অনুরূপ সিনট্যাক্স পেতে পারেন pandas। আপনি যদি ভাষাগুলি অদলবদল করতে চলেছেন, আপনি আরও চেষ্টা করতে পারেন, তবে প্রশ্নটি যা বলছে তা নয়
লিভিয়াস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.