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


116

পাইথনে, আমি জানি কীভাবে তালিকা থেকে আইটেমগুলি সরিয়ে ফেলা যায়।

item_list = ['item', 5, 'foo', 3.14, True]
item_list.remove('item')
item_list.remove(5)

এই উপরের কোডটি আইটেম_লিস্ট থেকে 5 এবং 'আইটেম' মান মুছে ফেলে। কিন্তু যখন সরানোর জন্য প্রচুর জিনিস থাকে তখন আমাকে অনেকগুলি লাইন লিখতে হয়

item_list.remove("something_to_remove")

আমি যদি সরিয়ে দিচ্ছি তার সূচকটি যদি আমি জানি তবে আমি ব্যবহার করি:

del item_list[x]

যেখানে x আমি যে আইটেমটি সরাতে চাইছি তার সূচক।

যদি আমি মুছে ফেলতে চাই এমন সমস্ত সংখ্যার সূচকটি জানি তবে আমি delসূচকগুলিতে আইটেমগুলিতে এক ধরণের লুপ ব্যবহার করব ।

তবে আমি যদি আইটেমগুলি সরাতে চাই তার সূচকগুলি না জানি?

আমি চেষ্টা করেছিলাম item_list.remove('item', 'foo'), তবে এই বলে আমি একটি ত্রুটি পেয়েছি যে removeকেবল একটি যুক্তি লাগে।

একক বিবৃতিতে তালিকা থেকে একাধিক আইটেম সরানোর কোনও উপায় আছে কি?

পিএস আমি ব্যবহার করেছি delএবং remove। এই দু'জনের মধ্যে পার্থক্য কি কেউ ব্যাখ্যা করতে পারেন, বা এগুলি কি একই?

ধন্যবাদ


4
আপনার দ্বিতীয় প্রশ্নের উত্তর দিতে: delকোনও আইটেমকে তার সূচক অনুসারে মুছবে। removeএকটি তালিকা ফাংশন একটি আইটেম এর সূচীতে খুঁজে বের করে এবং তারপর কল delসূচকের উপর।
অ্যারন

উত্তর:


174

পাইথনে, একটি নতুন অবজেক্ট তৈরি করা বিদ্যমান বিদ্যমান সংশোধন করার চেয়ে প্রায়শই ভাল:

item_list = ['item', 5, 'foo', 3.14, True]
item_list = [e for e in item_list if e not in ('item', 5)]

যা সমান:

item_list = ['item', 5, 'foo', 3.14, True]
new_list = []
for e in item_list:
    if e not in ('item', 5):
        new_list.append(e)
item_list = new_list

ফিল্টার আউট মানগুলির একটি বৃহত তালিকার ক্ষেত্রে (এখানে, ('item', 5)উপাদানগুলির একটি ছোট সেট) অপারেশন গড়ে ও (1) সময়ের জটিলতাset হওয়ায় দ্রুত ব্যবহার করা হয় । আপনি প্রথমে যে পুনরাবৃত্তিটি মুছে ফেলছেন তা তৈরি করাও ভাল ধারণা, যাতে আপনি তালিকা বোধের প্রতিটি পুনরাবৃত্তিতে এটি তৈরি করছেন না:in

unwanted = {'item', 5}
item_list = [e for e in item_list if e not in unwanted]

মেমরি সস্তা না হলে একটি ব্লুম ফিল্টারও একটি ভাল সমাধান is


সেটটি কি পাইথন 2 এ অপটিমাইজ করা হয়েছে বা এটি কেবল পাইথন 3 তে অনুকূলিত হয়েছে? তারমানে আমার অর্থ কি বাইটকোড উত্পন্ন হওয়ার পরে কেবল সেটটি তৈরি করা হবে?
হার 8

সংজ্ঞা অনুসারে সেটটি inঅপারেশনের জন্য অনুকূলিত । চারটি আদিম তথ্য কাঠামোর তুলনা করার জন্য এই মানদণ্ডটি দেখুন See হ্যাঁ, সেটটি প্রতিটি লুপে তৈরি করা হয়েছে , যেমন এখানে প্রস্তাবিত হয়েছে , ফলস্বরূপ জেনারেটর এক্সপ্রেশনটিতে ব্যবহারের জন্য সেটটি একটি ডেডিকেটেড ভেরিয়েবলে সংরক্ষণ করুন সময় বাঁচাতে পারে।
aluriak

20

আপনার তালিকাগুলিগুলিকে এসগুলিতে রূপান্তর setকরে এবং ব্যবহার করে আপনি এটি এক লাইনে করতে পারেন set.difference:

item_list = ['item', 5, 'foo', 3.14, True]
list_to_remove = ['item', 5, 'foo']

final_list = list(set(item_list) - set(list_to_remove))

আপনাকে নিম্নলিখিত আউটপুট দেবে:

final_list = [3.14, True]

দ্রষ্টব্য : এটি আপনার ইনপুট তালিকার সদৃশগুলি সরিয়ে ফেলবে এবং আউটপুটে থাকা উপাদানগুলি যে কোনও ক্রমে ( setকারণগুলি অর্ডার সংরক্ষণ করে না) হতে পারে। এটির জন্য আপনার উভয় তালিকার সমস্ত উপাদান হ্যাশযোগ্য হতে হবে


14
নাহ, এটি তালিকার আইটেমগুলিকে পরিবর্তন করে। কেবলমাত্র আইটেমগুলির ক্রম কোনও ব্যাপার না হলে এটি ব্যবহার করুন যা এটি প্রায়শই ঘটে।
স্ক্যাভেন্জার

6
এটি তালিকা থেকে সদৃশও সরিয়ে ফেলবে। উদাহরণস্বরূপ তালিকার জন্য যদিও এটি গুরুত্বপূর্ণ তা নয়
tschale

4
এটি নকল মুছে ফেলবে! উত্তরটি গুরুতর ত্রুটি সৃষ্টি করতে পারে, দয়া করে ব্যবহার করবেন না।
ব্যবহারকারী2698178

1

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


def removed(items, original_list, only_duplicates=False, inplace=False):
    """By default removes given items from original_list and returns
    a new list. Optionally only removes duplicates of `items` or modifies
    given list in place.
    """
    if not hasattr(items, '__iter__') or isinstance(items, str):
        items = [items]

    if only_duplicates:
        result = []
        for item in original_list:
            if item not in items or item not in result:
                result.append(item)
    else:
        result = [item for item in original_list if item not in items]

    if inplace:
        original_list[:] = result
    else:
        return result

দস্তাবেজ এক্সটেনশন:

"""
Examples:
---------

    >>>li1 = [1, 2, 3, 4, 4, 5, 5]
    >>>removed(4, li1)
       [1, 2, 3, 5, 5]
    >>>removed((4,5), li1)
       [1, 2, 3]
    >>>removed((4,5), li1, only_duplicates=True)
       [1, 2, 3, 4, 5]

    # remove all duplicates by passing original_list also to `items`.:
    >>>removed(li1, li1, only_duplicates=True)
      [1, 2, 3, 4, 5]

    # inplace:
    >>>removed((4,5), li1, only_duplicates=True, inplace=True)
    >>>li1
        [1, 2, 3, 4, 5]

    >>>li2 =['abc', 'def', 'def', 'ghi', 'ghi']
    >>>removed(('def', 'ghi'), li2, only_duplicates=True, inplace=True)
    >>>li2
        ['abc', 'def', 'ghi']
"""

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

li1 = [1, 2, 3, 4, 4, 5, 5]
li2 = li1
# then rebind li1 to the new list without the value 4
li1 = removed(4, li1)
# you end up with two separate lists where li2 is still pointing to the 
# original
li2
# [1, 2, 3, 4, 4, 5, 5]
li1
# [1, 2, 3, 5, 5]

এটি আপনি চান এমন আচরণ বা নাও হতে পারে।


1

আমি জানি না কেন প্রত্যেকে setপাইথন-এর আশ্চর্যজনক ক্ষমতা উল্লেখ করতে ভুলে গিয়েছিল । আপনি কেবলমাত্র একটি তালিকাতে আপনার তালিকাটি কাস্ট করতে পারেন এবং তারপরে আপনি যেমন সরল অভিব্যক্তিতে যা সরাতে চান তা মুছে ফেলতে পারেন:

>>> item_list = ['item', 5, 'foo', 3.14, True]
>>> item_list = set(item_list) - {'item', 5}
>>> item_list
{True, 3.14, 'foo'}
>>> # you can cast it again in a list-from like so
>>> item_list = list(item_list)
>>> item_list
[True, 3.14, 'foo']

6
যদিও বস্তুর ক্রম বজায় রাখে না।
এস্ট্রিড

4
এবং তালিকায় সম্ভাব্য বিদ্যমান নকলগুলিও সরিয়ে ফেলবে।
কিরিয়াকোস্টস্ট

"কেন সবাই [...] setএর উল্লেখ করতে ভুলে গেছেন "। কারণ তারা স্ট্যাকওভারফ্লো.com
বোরিস

1

আপনি ব্যবহার করতে পারেন filterfalse থেকে ফাংশন itertools মডিউল

উদাহরণ

import random
from itertools import filterfalse

random.seed(42)

data = [random.randrange(5) for _ in range(10)]
clean = [*filterfalse(lambda i: i == 0, data)]
print(f"Remove 0s\n{data=}\n{clean=}\n")


clean = [*filterfalse(lambda i: i in (0, 1), data)]
print(f"Remove 0s and 1s\n{data=}\n{clean=}")

আউটপুট:

Remove 0s
data=[0, 0, 2, 1, 1, 1, 0, 4, 0, 4]
clean=[2, 1, 1, 1, 4, 4]

Remove 0s and 1s
data=[0, 0, 2, 1, 1, 1, 0, 4, 0, 4]
clean=[2, 4, 4]

0

তবে আমি যদি আইটেমগুলি সরাতে চাই তার সূচকগুলি না জানি?

আপনি কেন পছন্দ করেন না তা আমি ঠিক বুঝতে পারি না rem তবে সরান তবে মান ব্যবহারের সাথে সম্পর্কিত প্রথম সূচক পেতে get সূচি (মান):

ind=item_list.index('item')

তারপরে সংশ্লিষ্ট মানটি সরান:

del item_list.pop[ind]

.index (মান) মানটির প্রথম উপস্থিতি পায় এবং .মেরাও (মান) মানের প্রথম উপস্থিতিটি সরিয়ে দেয়


আপনার যদি ফলাফল মানের প্রয়োজন না হয় del item_list[ind]তার পরিবর্তে ব্যবহার করার কথা বিবেচনা করুন pop
কোজিরো

-1

আপনি এটি ব্যবহার করতে পারেন -

মনে করুন আমাদের একটি তালিকা আছে, l = [1,2,3,4,5]

আমরা একক বিবৃতিতে শেষ দুটি আইটেম মুছতে চাই

del l[3:]

আমাদের আউটপুট আছে:

l = [1,2,3]

সহজবোধ্য রাখো

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