দুটি নেস্টেড তালিকার ছেদ খুঁজে?


468

আমি জানি দুটি ফ্ল্যাট তালিকার ছেদ কীভাবে পাওয়া যায়:

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]

অথবা

def intersect(a, b):
    return list(set(a) & set(b))

print intersect(b1, b2)

তবে যখন আমাকে নেস্টেড তালিকার জন্য ছেদ খুঁজতে হবে তখন আমার সমস্যাগুলি শুরু হয়:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

শেষ পর্যন্ত আমি গ্রহণ করতে চাই:

c3 = [[13,32],[7,13,28],[1,6]]

আপনি কি আমাকে এই দিয়ে একটি হাত দিতে পারেন?

সম্পর্কিত


সি 1 ছেদ করা সি 2 এর জন্য আপনার ছেদটি কী হবে? আপনি কি সহজেই সি 1 সি 2 এ সন্ধান করতে চান? অথবা আপনি সি 1-তে যে কোনও উপাদান সি -2-তে যে কোনও জায়গায় উপস্থিত খুঁজে পেতে চান?
ব্রায়ান আর বন্ডি

পড়ুন এই এবং অনুবাদক মধ্যে খেলা এবং খেলার।
পিথিকোস

উত্তর:


177

তুমি যদি চাও:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
c3 = [[13, 32], [7, 13, 28], [1,6]]

তারপরে পাইথন 2 এর জন্য আপনার সমাধানটি এখানে রয়েছে:

c3 = [filter(lambda x: x in c1, sublist) for sublist in c2]

পাইথন 3 এর filterপরিবর্তে একটি পুনরাবৃত্তযোগ্য ফিরে আসে list, সুতরাং আপনার filterসাথে কলগুলি মোড়ানো দরকার list():

c3 = [list(filter(lambda x: x in c1, sublist)) for sublist in c2]

ব্যাখ্যা:

ফিল্টার অংশটি প্রতিটি সাবলিস্টের আইটেম নেয় এবং এটি উত্স তালিকার সি 1 এ রয়েছে কিনা তা পরীক্ষা করে দেখায়। তালিকা অনুধাবন প্রতিটি উপ-তালিকার জন্য সি 2-তে কার্যকর করা হয়।


35
আপনি filter(set(c1).__contains__, sublist)দক্ষতার জন্য ব্যবহার করতে পারেন । বিটিডব্লিউ, এই সমাধানটির সুবিধা হ'ল filter()স্ট্রিং এবং টিপলস প্রকারগুলি সংরক্ষণ করে।
jfs

3
আমি এই পদ্ধতিটি পছন্দ করি তবে আমার ফলাফলের তালিকায় আমি ফাঁকা হয়ে যাচ্ছি
জোনাথন ওং

আমি পাইথন 3 কম্প্যাক্ট এখানে যুক্ত করেছি, যেহেতু আমি এটিকে পাইথন 3 প্রশ্নের ডুপের জন্য ডুপ টার্গেট হিসাবে ব্যবহার করছি
অ্যান্টি হাপাল

9
এটি নেস্টেড বোধগম্যতার সাথে আরও ভাল আইএমও পড়তে পারে:c3 = [[x for x in sublist if x in c1] for sublist in c2]
এরিক

894

ছেদটি সংজ্ঞায়িত করার দরকার নেই। এটি ইতিমধ্যে সেট একটি প্রথম শ্রেণির অংশ।

>>> b1 = [1,2,3,4,5,9,11,15]
>>> b2 = [4,5,6,7,8]
>>> set(b1).intersection(b2)
set([4, 5])

3
সেট এ রূপান্তরকরণের কারণে এটি ল্যাম্বদার চেয়ে ধীর হবে?
সিরো সান্তিলি :33 冠状 病 六四 事件

32
@ এসলট, এতে কোন ভুল আছে set(b1) & set(b2)? অপারেটরটি ব্যবহার করার জন্য এটির ক্লিনার আইএমও করুন।
gwg

4
এছাড়াও, ব্যবহারের setফলে কোডটি দ্রুততর আকারের অর্ডার হয়ে যাবে। এখানে একটি নমুনা বেঞ্চমার্ক®: gist.github.com/andersonvom/4d7e551b4c0418de3160
andersonvom

5
ফলাফলটি অর্ডার না করতে হলে কেবল কাজ করে।
বোরবাগ

7
তো ... এই উত্তরটি কোনওভাবেই প্রশ্নের উত্তর দেয় না, তাই না? কারণ এটি এখন নেস্টেড তালিকার সাথে কাজ করে ।
মায়ু 36

60

যে দুটি লোক কেবল দুটি তালিকার ছেদটি সন্ধান করতে চাইছে তাদের জন্য প্রশ্নকারী দুটি পদ্ধতি সরবরাহ করেছেন:

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]

এবং

def intersect(a, b):
     return list(set(a) & set(b))

print intersect(b1, b2)

তবে একটি হাইব্রিড পদ্ধতি রয়েছে যা আরও দক্ষ because

b1 = [1,2,3,4,5]
b2 = [3,4,5,6]
s2 = set(b2)
b3 = [val for val in b1 if val in s2]

এটি ও (এন) এ চলবে, তবে তালিকার বোঝার সাথে জড়িত তার আসল পদ্ধতিটি ও (এন ^ 2) এ চলবে whereas


যেমন "যদি ভাল ইন এস 2" ও (এন) তে সঞ্চালিত হয়, প্রস্তাবিত কোড স্নিপেট জটিলতা ও ও (এন ^ 2)
রোমেনো

8
উইকিপিপিথন.আর / মিন / টাইমকম্প্লেক্সিটি # সেট অনুসারে "ভ্যাল ইন এস 2" এর গড় কেস O (1) - সুতরাং এন ক্রিয়াকলাপগুলির মধ্যে প্রত্যাশিত সময়টি হ'ল (এন) (সবচেয়ে খারাপ ক্ষেত্রে সময় ও (কিনা) এন) বা ও (এন ^ 2) নির্ভর করে যে এই গড় কেসটি একটি বিভক্ত সময়কে উপস্থাপন করে বা না, তবে এটি অনুশীলনে খুব গুরুত্বপূর্ণ নয়)।
ডি কোয়েটজি

2
রানটাইমটি ও (এন) নয় কারণ এটি orক্যবদ্ধ হয়েছে তবে সেট সদস্যপদ গড় ও (1) হিসাবে রয়েছে (উদাহরণস্বরূপ যখন হ্যাশ টেবিল ব্যবহার করা হয়), এটি বড় পার্থক্য, উদাহরণস্বরূপ, কারণ স্বীকৃত সময় গ্যারান্টিযুক্ত।
miroB

28

কার্যকরী পদ্ধতির:

input_list = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7]]

result = reduce(set.intersection, map(set, input_list))

এবং এটি 1+ তালিকার আরও সাধারণ ক্ষেত্রে প্রয়োগ করা যেতে পারে


খালি ইনপুট তালিকা করার অনুমতি: set(*input_list[:1]).intersection(*input_list[1:])। Iterator সংস্করণ ( it = iter(input_list)): reduce(set.intersection, it, set(next(it, [])))। উভয় সংস্করণ সেট করতে সমস্ত ইনপুট তালিকা রূপান্তর করতে হবে না। পরেরটি আরও মেমরি দক্ষ।
jfs

from functools import reduceপাইথন 3 এ এটি ব্যবহার করতে ব্যবহার করুন Or বা আরও ভাল, একটি স্পষ্টত forলুপ ব্যবহার করুন ।
ত্রিগোনামিনিমা

27

খাঁটি তালিকা বোঝার সংস্করণ

>>> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
>>> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
>>> c1set = frozenset(c1)

ফ্ল্যাটেন বৈকল্পিক:

>>> [n for lst in c2 for n in lst if n in c1set]
[13, 32, 7, 13, 28, 1, 6]

নেস্টেড বৈকল্পিক:

>>> [[n for n in lst if n in c1set] for lst in c2]
[[13, 32], [7, 13, 28], [1, 6]]

20

& অপারেটর দুটি সেটকে ছেদ করে।

{1, 2, 3} & {2, 3, 4}
Out[1]: {2, 3}

ভাল, কিন্তু এই বিষয় তালিকার জন্য!
রাফা0809

3
দুটি তালিকার ছেদ ফলাফল একটি সেট তাই এই উত্তর পুরোপুরি বৈধ।
shrewmouse

তালিকায় সদৃশ মান থাকতে পারে তবে সেটগুলি দেয় না।
9:25 এ দর্শনীয় দেশ

13

2 টি তালিকার ছেদকে নিয়ে যাওয়ার একটি অজগর উপায়:

[x for x in list1 if x in list2]

2
এই প্রশ্নটি নেস্টেড তালিকা সম্পর্কে। আপনার উত্তর প্রশ্নের উত্তর দেয় না।
থমাস

8

আপনার এই কোডটি ব্যবহার করে ফ্ল্যাট করা উচিত ( http://kogs-www.informatik.uni-hamburg.de/~meine/python_t কৌশল থেকে নেওয়া ), কোডটি অনির্ধারিত, তবে আমি নিশ্চিত যে এটি কার্যকর করে:


def flatten(x):
    """flatten(sequence) -> list

    Returns a single, flat list which contains all elements retrieved
    from the sequence and all recursively contained sub-sequences
    (iterables).

    Examples:
    >>> [1, 2, [3,4], (5,6)]
    [1, 2, [3, 4], (5, 6)]
    >>> flatten([[[1,2,3], (42,None)], [4,5], [6], 7, MyVector(8,9,10)])
    [1, 2, 3, 42, None, 4, 5, 6, 7, 8, 9, 10]"""

    result = []
    for el in x:
        #if isinstance(el, (list, tuple)):
        if hasattr(el, "__iter__") and not isinstance(el, basestring):
            result.extend(flatten(el))
        else:
            result.append(el)
    return result

আপনি তালিকাটি সমতল করার পরে, আপনি স্বাভাবিকভাবে ছেদটি সম্পাদন করেন:


c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

def intersect(a, b):
     return list(set(a) & set(b))

print intersect(flatten(c1), flatten(c2))

2
এটি জিও ফ্ল্যাটিং কোডের একটি দুর্দান্ত বিট, তবে এটি প্রশ্নের উত্তর দেয় না। প্রশ্নকর্তা বিশেষত [[১৩,৩৩], [,,১,,২৮], [১, the]] আকারে ফলাফলটি প্রত্যাশা করে।
রব ইয়ং

8

যেহেতু intersectসংজ্ঞায়িত হয়েছিল, একটি প্রাথমিক তালিকা বোঝাপড়া যথেষ্ট:

>>> c3 = [intersect(c1, i) for i in c2]
>>> c3
[[32, 13], [28, 13, 7], [1, 6]]

এস লট এর মন্তব্য এবং টিএম এর সম্পর্কিত মন্তব্যকে উন্নতি ধন্যবাদ:

>>> c3 = [list(set(c1).intersection(i)) for i in c2]
>>> c3
[[32, 13], [28, 13, 7], [1, 6]]

5

প্রদত্ত:

> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]

> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

আমি নীচের কোডটি ভালভাবে কাজ করে এবং সেট ক্রিয়াকলাপটি ব্যবহার করলে আরও সংক্ষিপ্ততর হতে পারে:

> c3 = [list(set(f)&set(c1)) for f in c2] 

এটা পেয়েছিলাম:

> [[32, 13], [28, 13, 7], [1, 6]]

যদি অর্ডার প্রয়োজন হয়:

> c3 = [sorted(list(set(f)&set(c1))) for f in c2] 

আমরা পেয়েছি:

> [[13, 32], [7, 13, 28], [1, 6]]

যাইহোক, আরও অজগর শৈলীর জন্য, এটি খুব ভাল:

> c3 = [ [i for i in set(f) if i in c1] for f in c2]

3

আমি জানি না আপনার প্রশ্নের উত্তর দিতে দেরি হচ্ছে কিনা। আপনার প্রশ্নটি পড়ার পরে আমি একটি ফাংশন ছেদ করে () নিয়ে এসেছি যা উভয় তালিকায় এবং নেস্টেড তালিকায় কাজ করতে পারে। আমি এই ফাংশনটি সংজ্ঞায়িত করতে পুনরাবৃত্তি ব্যবহার করেছি, এটি খুব স্বজ্ঞাত। আশা করি এটি আপনি যা খুঁজছেন:

def intersect(a, b):
    result=[]
    for i in b:
        if isinstance(i,list):
            result.append(intersect(a,i))
        else:
            if i in a:
                 result.append(i)
    return result

উদাহরণ:

>>> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
>>> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
>>> print intersect(c1,c2)
[[13, 32], [7, 13, 28], [1, 6]]

>>> b1 = [1,2,3,4,5,9,11,15]
>>> b2 = [4,5,6,7,8]
>>> print intersect(b1,b2)
[4, 5]

2

আপনি কি [1,2]ছেদ করতে বিবেচনা করেন [1, [2]]? অর্থাৎ, এটি কি কেবল আপনার যত্ন নেওয়া নম্বরগুলি বা তালিকার কাঠামোর পাশাপাশি?

যদি কেবল সংখ্যাগুলি থাকে তবে কীভাবে তালিকাগুলি "সমতল" করবেন তা তদন্ত করুন, তারপরে set()পদ্ধতিটি ব্যবহার করুন ।


আমি তালিকার কাঠামোটি অপরিবর্তিত রেখে দিতে চাই।
elfuego1

1

আমি এটি করার উপায়ও খুঁজছিলাম এবং শেষ পর্যন্ত এটি এর মতো শেষ হয়েছিল:

def compareLists(a,b):
    removed = [x for x in a if x not in b]
    added = [x for x in b if x not in a]
    overlap = [x for x in a if x in b]
    return [removed,added,overlap]

যদি set.intersication ব্যবহার না করে থাকেন তবে এই সাধারণ একটি লাইনারগুলি হ'ল আমিও করতাম।
জবাই

0
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]

c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

c3 = [list(set(c2[i]).intersection(set(c1))) for i in xrange(len(c2))]

c3
->[[32, 13], [28, 13, 7], [1, 6]]

0

আমরা এর জন্য সেট পদ্ধতিগুলি ব্যবহার করতে পারি:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

   result = [] 
   for li in c2:
       res = set(li) & set(c1)
       result.append(list(res))

   print result

0

ছেদগুলি সংজ্ঞায়িত করতে যা উপাদানগুলির ব্যবহারের কার্ডিনালটি সঠিকভাবে বিবেচনা করে Counter:

from collections import Counter

>>> c1 = [1, 2, 2, 3, 4, 4, 4]
>>> c2 = [1, 2, 4, 4, 4, 4, 5]
>>> list((Counter(c1) & Counter(c2)).elements())
[1, 2, 4, 4, 4]

0
# Problem:  Given c1 and c2:
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
# how do you get c3 to be [[13, 32], [7, 13, 28], [1, 6]] ?

সেট করার একটি উপায় এখানে c3সেটগুলিতে জড়িত নয়:

c3 = []
for sublist in c2:
    c3.append([val for val in c1 if val in sublist])

তবে আপনি যদি কেবল একটি লাইন ব্যবহার করতে পছন্দ করেন তবে আপনি এটি করতে পারেন:

c3 = [[val for val in c1 if val in sublist]  for sublist in c2]

এটি একটি তালিকা বোঝার ভিতরে একটি তালিকা বোধ, যা কিছুটা অস্বাভাবিক, তবে আমি মনে করি এটি অনুসরণ করে আপনার খুব বেশি সমস্যা হওয়া উচিত নয়।


0
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
c3 = [list(set(i) & set(c1)) for i in c2]
c3
[[32, 13], [28, 13, 7], [1, 6]]

আমার জন্য এটি খুব মার্জিত এবং এটির দ্রুত উপায় :)


0

ফ্ল্যাট তালিকা reduceসহজেই তৈরি করা যেতে পারে।

আপনার প্রাথমিক ব্যবহার করা দরকার - reduceফাংশনে তৃতীয় যুক্তি ।

reduce(
   lambda result, _list: result.append(
       list(set(_list)&set(c1)) 
     ) or result, 
   c2, 
   [])

উপরের কোডটি পাইথন 2 এবং পাইথন 3 উভয়ের পক্ষে কাজ করে তবে আপনাকে হ্রাস মডিউল হিসাবে আমদানি করতে হবে from functools import reduce। বিস্তারিত জানার জন্য নীচের লিঙ্কটি দেখুন।


-1

পুনরাবৃত্তের মধ্যে পার্থক্য এবং ছেদটি সন্ধান করার সহজ উপায়

পুনরাবৃত্তি গুরুত্বপূর্ণ হলে এই পদ্ধতিটি ব্যবহার করুন

from collections import Counter

def intersection(a, b):
    """
    Find the intersection of two iterables

    >>> intersection((1,2,3), (2,3,4))
    (2, 3)

    >>> intersection((1,2,3,3), (2,3,3,4))
    (2, 3, 3)

    >>> intersection((1,2,3,3), (2,3,4,4))
    (2, 3)

    >>> intersection((1,2,3,3), (2,3,4,4))
    (2, 3)
    """
    return tuple(n for n, count in (Counter(a) & Counter(b)).items() for _ in range(count))

def difference(a, b):
    """
    Find the symmetric difference of two iterables

    >>> difference((1,2,3), (2,3,4))
    (1, 4)

    >>> difference((1,2,3,3), (2,3,4))
    (1, 3, 4)

    >>> difference((1,2,3,3), (2,3,4,4))
    (1, 3, 4, 4)
    """
    diff = lambda x, y: tuple(n for n, count in (Counter(x) - Counter(y)).items() for _ in range(count))
    return diff(a, b) + diff(b, a)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.