عناصر تکراری را از یک لیست (آرایه) در پایتون حذف و استخراج کنید

کسب و کار

این بخش نحوه تولید یک لیست جدید در پایتون با حذف یا استخراج عناصر تکراری از یک لیست (آرایه) را توضیح می دهد.

جزئیات زیر در اینجا شرح داده شده است.

  • عناصر تکراری را حذف کنید و لیست های جدید ایجاد کنید
    • ترتیب فهرست اصلی را حفظ نکنید:set()
    • ترتیب فهرست اصلی را حفظ می کند:dict.fromkeys()،sorted()
    • آرایه دو بعدی (لیست لیست ها)
  • عناصر تکراری را استخراج کنید و یک لیست جدید ایجاد کنید
    • ترتیب فهرست اصلی را حفظ نکنید
    • ترتیب فهرست اصلی را حفظ می کند
    • آرایه دو بعدی (لیست لیست ها)

همین مفهوم را می توان به جای لیست ها در مورد تاپل ها اعمال کرد.

برای مشاهده مقاله زیر

  • اگر می خواهید تعیین کنید که آیا یک لیست یا تاپل دارای عناصر تکراری است یا خیر
  • اگر می‌خواهید به جای یک فهرست، عناصری را استخراج کنید که در بین فهرست‌های متعدد مشترک هستند یا رایج نیستند

توجه داشته باشید که لیست ها می توانند انواع مختلفی از داده ها را ذخیره کنند و کاملاً با آرایه ها متفاوت هستند. اگر می‌خواهید آرایه‌هایی را در فرآیندهایی مدیریت کنید که به اندازه حافظه و آدرس‌های حافظه یا پردازش عددی داده‌های بزرگ نیاز دارند، از آرایه (کتابخانه استاندارد) یا NumPy استفاده کنید.

عناصر تکراری را حذف کنید و لیست های جدید ایجاد کنید

ترتیب فهرست اصلی را حفظ نکنید:set()

اگر نیازی به حفظ ترتیب لیست اصلی نیست، از set() استفاده کنید که مجموعه ای از نوع مجموعه را تولید می کند.

نوع مجموعه یک نوع داده است که هیچ عنصر تکراری ندارد. هنگامی که یک لیست یا نوع داده دیگری به set() داده می شود، مقادیر تکراری نادیده گرفته می شوند و یک شی از نوع مجموعه بازگردانده می شود که در آن فقط مقادیر منحصر به فرد عناصر هستند.

اگر می خواهید آن را تاپلی کنید، از () tuple استفاده کنید.

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

print(set(l))
# {1, 2, 3, 4, 5}

print(list(set(l)))
# [1, 2, 3, 4, 5]

البته می توان آن را به صورت تنظیم شده نیز رها کرد. برای اطلاعات بیشتر در مورد مجموعه نوع ست به مقاله زیر مراجعه کنید.

ترتیب فهرست اصلی را حفظ می کند:dict.fromkeys()،sorted()

اگر می‌خواهید ترتیب لیست اصلی را حفظ کنید، از متد کلاس fromkeys() از نوع دیکشنری یا تابع داخلی sorted() استفاده کنید.

dict.fromkeys() یک شی دیکشنری جدید ایجاد می کند که کلیدهای آن لیست ها، تاپل ها و غیره مشخص شده در آرگومان ها هستند. اگر آرگومان دوم حذف شود، مقدار None است.

از آنجایی که کلیدهای دیکشنری عناصر تکراری ندارند، مقادیر تکراری مانند set() نادیده گرفته می شوند. علاوه بر این، یک شی دیکشنری می تواند به عنوان آرگومان به list() ارسال شود تا لیستی به دست آید که عناصر آن کلیدهای دیکشنری هستند.

print(dict.fromkeys(l))
# {3: None, 2: None, 1: None, 5: None, 4: None}

print(list(dict.fromkeys(l)))
# [3, 2, 1, 5, 4]

از پایتون 3.7 (CPython 3.6 است) تضمین شده است که dict.fromkeys() ترتیب توالی آرگومان را حفظ می کند. نسخه های قبلی از تابع داخلی sorted() به صورت زیر استفاده می کنند.

لیست tuple متد index() را برای کلید آرگومان مرتب شده مشخص کنید، که لیست مرتب شده ای از عناصر را برمی گرداند.

index() متدی است که شاخص مقدار (تعداد عنصر در لیست) را برمی گرداند که می تواند به عنوان کلید sorted() برای مرتب کردن لیست بر اساس ترتیب لیست اصلی مشخص شود. کلید آرگومان به عنوان یک شیء قابل فراخوانی (callable) مشخص شده است، بنابراین () را ننویسید.

print(sorted(set(l), key=l.index))
# [3, 2, 1, 5, 4]

آرایه دو بعدی (لیست لیست ها)

برای آرایه‌های دو بعدی (لیست لیست‌ها)، روشی که از set() یا dict.fromkeys() استفاده می‌کند منجر به TypeError می‌شود.

l_2d = [[1, 1], [0, 1], [0, 1], [0, 0], [1, 0], [1, 1], [1, 1]]

# l_2d_unique = list(set(l_2d))
# TypeError: unhashable type: 'list'

# l_2d_unique_order = dict.fromkeys(l_2d)
# TypeError: unhashable type: 'list'

این به این دلیل است که اشیاء غیرقابل هش مانند لیست ها نمی توانند عناصری از نوع مجموعه یا کلیدهایی از نوع dict باشند.

توابع زیر را تعریف کنید ترتیب لیست اصلی حفظ می شود و برای لیست ها و تاپل های یک بعدی کار می کند.

def get_unique_list(seq):
    seen = []
    return [x for x in seq if x not in seen and not seen.append(x)]

print(get_unique_list(l_2d))
# [[1, 1], [0, 1], [0, 0], [1, 0]]

print(get_unique_list(l))
# [3, 2, 1, 5, 4]

از نماد درک لیست استفاده می شود.

در اینجا از موارد زیر استفاده می کنیم

  • اگر X در “X و Y” در ارزیابی اتصال کوتاه عملگر و نادرست باشد، آنگاه Y ارزیابی نمی شود (اجرا نمی شود).
  • متد append() None را برمی گرداند.

اگر عناصر لیست اصلی seq در See وجود نداشته باشند، سپس و after ارزیابی می شوند.
see.append(x) اجرا می شود و عنصر به see اضافه می شود.
از آنجایی که متد append() None را برمی گرداند و None is False است، not seen.append(x) به True ارزیابی می کند.
عبارت شرطی در نماد درک لیست به True تبدیل می شود و به عنوان عنصری از لیست تولید شده نهایی اضافه می شود.

اگر عناصر لیست اصلی seq در See وجود داشته باشند، x not in seen False است و عبارت شرطی برای عبارت درک لیست False است.
بنابراین، آنها به عنوان عناصر لیست تولید شده نهایی اضافه نمی شوند.

روش دیگر تنظیم محور آرگومان در تابع np.unique() NumPy است، اگرچه نتیجه مرتب خواهد شد.

عناصر تکراری را استخراج کنید و یک لیست جدید ایجاد کنید

ترتیب فهرست اصلی را حفظ نکنید

برای استخراج فقط عناصر تکراری از لیست اصلی، از collections.Counter() استفاده کنید.
یک مجموعه را برمی‌گرداند. شمارنده (یک زیر کلاس از فرهنگ لغت) با عناصر به عنوان کلید و تعداد عناصر به عنوان مقادیر.

import collections

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

print(collections.Counter(l))
# Counter({3: 3, 2: 2, 1: 2, 5: 1, 4: 1})

از آنجایی که زیر کلاس فرهنگ لغت است، آیتم() می تواند برای بازیابی کلیدها و مقادیر استفاده شود. استخراج کلیدهایی که تعداد آنها دو یا بیشتر است کافی است.

print([k for k, v in collections.Counter(l).items() if v > 1])
# [3, 2, 1]

ترتیب فهرست اصلی را حفظ می کند

همانطور که در مثال بالا نشان داده شده است، از پایتون 3.7، کلیدهای مجموعه ها. شمارنده ترتیب لیست اصلی و غیره را حفظ می کند.

در نسخه های قبلی، مرتب سازی با sorted() و همچنین حذف عناصر تکراری کافی است.

print(sorted([k for k, v in collections.Counter(l).items() if v > 1], key=l.index))
# [3, 2, 1]

اگر می‌خواهید موارد تکراری را همانطور که هستند استخراج کنید، به سادگی عناصر را از لیست اصلی با تعدادی دو یا بیشتر بگذارید. نظم نیز حفظ شده است.

cc = collections.Counter(l)
print([x for x in l if cc[x] > 1])
# [3, 3, 2, 1, 1, 2, 3]

آرایه دو بعدی (لیست لیست ها)

برای آرایه های دو بعدی (فهرست لیست ها)، به ترتیب زمانی که ترتیب لیست اصلی حفظ نمی شود و زمانی که حفظ می شود، عملکردهای زیر امکان پذیر است. همچنین برای لیست ها و تاپل های یک بعدی کار می کند.

l_2d = [[1, 1], [0, 1], [0, 1], [0, 0], [1, 0], [1, 1], [1, 1]]
def get_duplicate_list(seq):
    seen = []
    return [x for x in seq if not seen.append(x) and seen.count(x) == 2]

def get_duplicate_list_order(seq):
    seen = []
    return [x for x in seq if seq.count(x) > 1 and not seen.append(x) and seen.count(x) == 1]

print(get_duplicate_list(l_2d))
# [[0, 1], [1, 1]]

print(get_duplicate_list_order(l_2d))
# [[1, 1], [0, 1]]

print(get_duplicate_list(l))
# [3, 1, 2]

print(get_duplicate_list_order(l))
# [3, 2, 1]

اگر می خواهید با موارد تکراری استخراج کنید، عناصر را از لیست اصلی با تعداد دو یا بیشتر بگذارید.

print([x for x in l_2d if l_2d.count(x) > 1])
# [[1, 1], [0, 1], [0, 1], [1, 1], [1, 1]]

توجه داشته باشید که از آنجایی که پیچیدگی محاسباتی count() O(n) است، تابع نشان داده شده در بالا که به طور مکرر count() را اجرا می کند بسیار ناکارآمد است. ممکن است راه هوشمندتری وجود داشته باشد.

Counter یک زیر کلاس از فرهنگ لغت است، بنابراین اگر یک لیست یا چند تایی که عناصر آن لیست یا سایر اشیاء غیرقابل هش هستند را به collections ارسال کنید.Counter()، خطایی رخ می دهد و نمی توانید از آن استفاده کنید.

# print(collections.Counter(l_2d))
# TypeError: unhashable type: 'list'
Copied title and URL