Python में नेस्टेड सूची (सूची की सूची) से उन पंक्तियों को फ़िल्टर करना जिनमें दी गई उप-सूची के सभी तत्व मौजूद हों।
समस्या
दिया गया: my_list = [[8, 6, 3, 2], [1, 6], [2, 1, 7], [8, 1, 2]] और sub_list = [1, 2]
निकालें: वे पंक्तियाँ जिनमें 1 और 2 दोनों मौजूद हों।
उदाहरण
my_list = [[8, 6, 3, 2], [1, 6], [2, 1, 7], [8, 1, 2]]
sub_list = [1, 2]
print("मूल सूची:", my_list)
print("खोजने वाले तत्व:", sub_list)
# विधि 1: लूप और फ्लैग (मूल लेख)
result = []
for row in my_list:
flag = True
for element in sub_list:
if element not in row:
flag = False
break
if flag:
result.append(row)
print("परिणाम (लूप):", result)
# विधि 2: all() + जनरेटर (अधिक पायथनिक)
result2 = [row for row in my_list if all(elem in row for elem in sub_list)]
print("परिणाम (all + comprehension):", result2)
# विधि 3: सेट ऑपरेशन्स (सबसे तेज़ बड़े डेटा के लिए)
sub_set = set(sub_list)
result3 = [row for row in my_list if sub_set.issubset(row)]
print("परिणाम (set.issubset):", result3)
आउटपुट
मूल सूची: [[8, 6, 3, 2], [1, 6], [2, 1, 7], [8, 1, 2]]
खोजने वाले तत्व: [1, 2]
परिणाम (लूप): [[2, 1, 7], [8, 1, 2]]
परिणाम (all + comprehension): [[2, 1, 7], [8, 1, 2]]
परिणाम (set.issubset): [[2, 1, 7], [8, 1, 2]]
व्याख्या
| पंक्ति | तत्व | 1 मौजूद? | 2 मौजूद? | दोनों? |
|---|---|---|---|---|
| [8, 6, 3, 2] | 8,6,3,2 | नहीं | हां | नहीं |
| [1, 6] | 1,6 | हां | नहीं | नहीं |
| [2, 1, 7] | 2,1,7 | हां | हां | हां |
| [8, 1, 2] | 8,1,2 | हां | हां | हां |
फंक्शन के रूप में
def filter_rows_with_all_elements(matrix, required_elements):
"""उन पंक्तियों को लौटाएं जिनमें सभी आवश्यक तत्व मौजूद हों"""
req_set = set(required_elements)
return [row for row in matrix if req_set.issubset(row)]
# उपयोग
data = [[8, 6, 3, 2], [1, 6], [2, 1, 7], [8, 1, 2]]
print(filter_rows_with_all_elements(data, [1, 2])) # [[2, 1, 7], [8, 1, 2]]
print(filter_rows_with_all_elements(data, [1, 2, 8])) # [[8, 1, 2]]
print(filter_rows_with_all_elements(data, [6])) # [[8, 6, 3, 2], [1, 6]]
print(filter_rows_with_all_elements(data, [99])) # []
Pandas DataFrame में उपयोग
import pandas as pd
df = pd.DataFrame({
'A': [8, 1, 2, 8],
'B': [6, 6, 1, 1],
'C': [3, None, 7, 2],
'D': [2, None, None, None]
})
print("DataFrame:\n", df)
# पंक्तियाँ जहां A=1 और B=1 दोनों हों (उदाहरण)
# वास्तविक उपयोग: किसी भी कॉलम में मान खोजें
required = {1, 2}
# प्रत्येक पंक्ति को सेट में बदलकर जांचें
mask = df.apply(lambda row: required.issubset(set(row.dropna())), axis=1)
filtered = df[mask]
print("\n1 और 2 दोनों वाली पंक्तियाँ:\n", filtered)
उन्नत: क्रम भी मायने रखता है (सबसीक्वेंस)
def is_subsequence(row, sub):
"""जांचें कि sub, row का सबसीक्वेंस है (क्रम बनाए रखते हुए)"""
it = iter(row)
return all(elem in it for elem in sub)
# क्रम महत्वपूर्ण: [1, 2] क्रम में होना चाहिए
data = [[1, 2, 3], [2, 1, 3], [1, 3, 2], [4, 1, 5, 2]]
print("क्रम महत्वपूर्ण (सबसीक्वेंस):")
for row in data:
print(f" {row}: {is_subsequence(row, [1, 2])}")
# आउटपुट:
# [1, 2, 3]: True
# [2, 1, 3]: False
# [1, 3, 2]: True (1 फिर 2)
# [4, 1, 5, 2]: True
प्रदर्शन तुलना
import timeit
# बड़ी सूची
large_list = [list(range(i, i+10)) for i in range(1000)]
sub = [5, 6, 7]
# समय मापें
t1 = timeit.timeit(lambda: [r for r in large_list if all(e in r for e in sub)], number=100)
t2 = timeit.timeit(lambda: [r for r in large_list if set(sub).issubset(r)], number=100)
print(f"all() + in: {t1:.4f}s")
print(f"set.issubset: {t2:.4f}s") # आमतौर पर तेज़