Python میں فہرست (سرنی) سے ڈپلیکیٹ عناصر کو ہٹائیں اور نکالیں۔

کاروبار

یہ سیکشن بیان کرتا ہے کہ کس طرح ایک فہرست (سرنی) سے ڈپلیکیٹ عناصر کو ہٹا کر یا نکال کر ازگر میں نئی ​​فہرست تیار کی جائے۔

مندرجہ ذیل تفصیلات یہاں بیان کی گئی ہیں۔

  • ڈپلیکیٹ عناصر کو ہٹا دیں اور نئی فہرستیں بنائیں
    • اصل فہرست کی ترتیب کو محفوظ نہ رکھیں:set()
    • اصل فہرست کی ترتیب کو محفوظ رکھتا ہے۔:dict.fromkeys(),sorted()
    • دو جہتی صف (فہرستوں کی فہرست)
  • ڈپلیکیٹ عناصر کو نکالیں اور ایک نئی فہرست بنائیں
    • اصل فہرست کی ترتیب کو محفوظ نہ رکھیں
    • اصل فہرست کی ترتیب کو محفوظ رکھتا ہے۔
    • دو جہتی صف (فہرستوں کی فہرست)

اسی تصور کو فہرستوں کے بجائے ٹیپلز پر لاگو کیا جا سکتا ہے۔

کے لیے درج ذیل مضمون کو دیکھیں

  • اگر آپ اس بات کا تعین کرنا چاہتے ہیں کہ آیا کسی فہرست یا ٹوپل میں ڈپلیکیٹ عناصر ہیں۔
  • اگر آپ ایسے عناصر کو نکالنا چاہتے ہیں جو ایک فہرست کے بجائے ایک سے زیادہ فہرستوں میں عام ہیں یا عام نہیں ہیں۔

نوٹ کریں کہ فہرستیں مختلف قسم کے ڈیٹا کو محفوظ کر سکتی ہیں اور صفوں سے بالکل مختلف ہیں۔ اگر آپ ایسے پراسیس میں صفوں کو ہینڈل کرنا چاہتے ہیں جن کے لیے میموری کا سائز اور میموری ایڈریسز یا بڑے ڈیٹا کی عددی پروسیسنگ کی ضرورت ہوتی ہے، تو array (معیاری لائبریری) یا NumPy استعمال کریں۔

ڈپلیکیٹ عناصر کو ہٹا دیں اور نئی فہرستیں بنائیں

اصل فہرست کی ترتیب کو محفوظ نہ رکھیں:set()

اگر اصل فہرست کی ترتیب کو محفوظ رکھنے کی ضرورت نہیں ہے، تو set() کا استعمال کریں، جو ایک سیٹ ٹائپ سیٹ تیار کرتا ہے۔

سیٹ کی قسم ایک ڈیٹا کی قسم ہے جس میں کوئی ڈپلیکیٹ عناصر نہیں ہیں۔ جب کسی فہرست یا دیگر ڈیٹا کی قسم کو set() میں منتقل کیا جاتا ہے، تو ڈپلیکیٹ قدروں کو نظر انداز کر دیا جاتا ہے اور قسم کے سیٹ کا ایک آبجیکٹ واپس کر دیا جاتا ہے جس میں صرف منفرد اقدار عناصر ہوتے ہیں۔

اگر آپ اسے ٹیپل بنانا چاہتے ہیں تو ٹیپل () استعمال کریں۔

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()

اگر آپ اصل فہرست کی ترتیب کو برقرار رکھنا چاہتے ہیں تو لغت کی قسم کے کلیس کا طریقہ () یا بلٹ ان فنکشن sorted() استعمال کریں۔

dict.fromkeys() ایک نیا لغت آبجیکٹ بناتا ہے جس کی کلیدیں فہرستیں، ٹیپلز وغیرہ ہیں جو دلائل میں بیان کی گئی ہیں۔ اگر دوسری دلیل کو چھوڑ دیا جائے تو قدر کوئی نہیں ہے۔

چونکہ ڈکشنری کیز میں ڈپلیکیٹ عناصر نہیں ہوتے، اس لیے ڈپلیکیٹ اقدار کو سیٹ() کی طرح نظر انداز کر دیا جاتا ہے۔ اس کے علاوہ، ایک لغت آبجیکٹ کو ایک دلیل کے طور پر 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]

Python 3.7 (CPython 3.6 ہے) کے بعد سے اس بات کی ضمانت دی گئی ہے کہ dict.fromkeys() دلیل کی ترتیب کو محفوظ رکھتا ہے۔ اس سے پہلے کے ورژن بلٹ ان فنکشن sorted() کو حسب ذیل استعمال کرتے ہیں۔

ترتیب شدہ کی دلیل کلید کے لئے فہرست ٹیپل میتھڈ انڈیکس () کی وضاحت کریں، جو عناصر کی ترتیب شدہ فہرست کو لوٹاتا ہے۔

index() ایک ایسا طریقہ ہے جو قیمت کا اشاریہ (فہرست میں عنصر کی تعداد) واپس کرتا ہے، جسے اصل فہرست کی ترتیب کی بنیاد پر فہرست کو ترتیب دینے کے لیے sorted() کی کلید کے طور پر بیان کیا جا سکتا ہے۔ دلیل کی کلید ایک قابل کال (کالبل) آبجیکٹ کے طور پر بیان کی گئی ہے، لہذا () نہ لکھیں۔

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'

اس کی وجہ یہ ہے کہ غیر ہیش ایبل اشیاء جیسے فہرستیں ٹائپ سیٹ کے عناصر یا ٹائپ ڈیکٹ کی کلید نہیں ہوسکتی ہیں۔

مندرجہ ذیل افعال کی وضاحت کریں اصل فہرست کی ترتیب محفوظ ہے اور ایک جہتی فہرستوں اور ٹیپلس کے لیے کام کرتی ہے۔

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 اور Y” میں X اور آپریٹر کی شارٹ سرکٹ تشخیص میں غلط ہے، تو Y کی تشخیص نہیں کی جاتی ہے (عمل نہیں کیا جاتا ہے)۔
  • ضمیمہ () طریقہ کوئی نہیں لوٹاتا ہے۔

اگر اصل فہرست سیق کے عناصر دیکھے ہوئے میں موجود نہیں ہیں، تو پھر اور بعد کا جائزہ لیا جاتا ہے۔
see.append(x) کو پھانسی دی جاتی ہے اور عنصر کو دیکھا میں شامل کیا جاتا ہے۔
کیونکہ ضمیمہ () طریقہ None کو نہیں لوٹاتا ہے اور None is False, not seen.append(x) کی تشخیص درست ہے۔
فہرست فہمی اشارے میں مشروط اظہار درست ہو جاتا ہے اور حتمی تیار کردہ فہرست کے عنصر کے طور پر شامل کیا جاتا ہے۔

اگر اصل فہرست سیق کے عناصر دیکھے ہوئے میں موجود ہیں، تو x نہیں دیکھا گیا غلط ہے، اور فہرست کی تفہیم کے اظہار کے لیے مشروط اظہار غلط ہے۔
لہذا، وہ حتمی تیار کردہ فہرست کے عناصر کے طور پر شامل نہیں کیے گئے ہیں۔

دوسرا طریقہ NumPy کے فنکشن np.unique() میں دلیل کا محور سیٹ کرنا ہے، حالانکہ نتیجہ ترتیب دیا جائے گا۔

ڈپلیکیٹ عناصر کو نکالیں اور ایک نئی فہرست بنائیں

اصل فہرست کی ترتیب کو محفوظ نہ رکھیں

اصل فہرست سے صرف ڈپلیکیٹ عناصر نکالنے کے لیے، 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]]

نوٹ کریں کہ چونکہ شمار () کی کمپیوٹیشنل پیچیدگی O(n) ہے، اس لیے اوپر دکھایا گیا فنکشن جو بار بار count() کو انجام دیتا ہے بہت غیر موثر ہے۔ کوئی ہوشیار طریقہ ہو سکتا ہے۔

کاؤنٹر لغت کا ایک ذیلی طبقہ ہے، اس لیے اگر آپ کوئی ایسی فہرست یا ٹیپل پاس کرتے ہیں جس کے عناصر کی فہرستیں ہیں یا دیگر نان ہیش ایبل اشیاء کو کلیکشنز۔ کاؤنٹر() میں، ایک خرابی پیدا ہو جائے گی اور آپ اسے استعمال نہیں کر سکیں گے۔

# print(collections.Counter(l_2d))
# TypeError: unhashable type: 'list'