मैं Flatten (an irregular) list of lists पढ़ रहा था और इसे पायथन अभ्यास के रूप में अपनाने का फैसला किया - एक छोटा सा फ़ंक्शन जिसे मैं कभी-कभी अभ्यास के लिए, मूल का जिक्र किए बिना फिर से लिखूंगा। पहली बार मैं इस कोशिश की, मैं निम्नलिखित की तरह कुछ था:मैं कैसे निर्धारित कर सकता हूं कि एक कंटेनर असीम रूप से रिकर्सिव है और इसका सबसे छोटा अद्वितीय कंटेनर ढूंढता है?
def flat(iterable):
try:
iter(iterable)
except TypeError:
yield iterable
else:
for item in iterable:
yield from flatten(item)
यह नेस्ट list
संख्या से युक्त रों जैसी बुनियादी संरचनाओं के लिए ठीक काम करता है, लेकिन तार यह दुर्घटना क्योंकि श्रृंखला का पहला तत्व एक एकल चरित्र है स्ट्रिंग, जिसका पहला तत्व स्वयं है, जिसका पहला तत्व स्वयं ही है, और इसी तरह। उपरोक्त लिंक को जांचते हुए, मुझे एहसास हुआ कि स्ट्रिंग के लिए चेक बताता है।
def flatter(iterable):
try:
iter(iterable)
if isinstance(iterable, str):
raise TypeError
except TypeError:
yield iterable
else:
for item in iterable:
yield from flatten(item)
अब यह रूप में अच्छी तरह तार के लिए काम करता है: जो मुझे निम्नलिखित दे दी है। हालांकि, मैंने तब याद किया कि list
में स्वयं के संदर्भ हो सकते हैं।
>>> lst = []
>>> lst.append(lst)
>>> lst
[[...]]
>>> lst[0][0][0][0] is lst
True
तो, एक स्ट्रिंग केवल प्रकार है कि समस्या की इस तरह का कारण बन सकता है। इस बिंदु पर, मैंने स्पष्ट समस्या-जांच के बिना इस मुद्दे के खिलाफ सुरक्षा के लिए एक रास्ता तलाशना शुरू कर दिया।
निम्नलिखित flattener.py
ensued। flattish()
एक ऐसा संस्करण है जो केवल तारों के लिए जांच करता है। flatten_notype()
जांच करता है कि किसी वस्तु का पहला आइटम का पहला आइटम रिकर्सन निर्धारित करने के लिए स्वयं के बराबर है या नहीं। flatten()
यह करता है और फिर जांच करता है कि ऑब्जेक्ट या उसके पहले आइटम का पहला आइटम दूसरे प्रकार का उदाहरण है या नहीं। Fake
कक्षा मूल रूप से अनुक्रमों के लिए एक रैपर को परिभाषित करती है। प्रत्येक फ़ंक्शन का परीक्षण करने वाली रेखाओं पर टिप्पणियां should be `desired_result` [> `undesired_actual_result`]
रूप में परिणामों का वर्णन करती हैं। जैसा कि आप देख सकते हैं, प्रत्येक एक स्ट्रिंग के चारों ओर लिपटा Fake
पर विभिन्न तरीकों से विफल रहता है, Fake
पूर्णांकों, एकल चरित्र तार, और बहु-चरित्र स्ट्रिंग की एक list
के चारों ओर लिपटा।
>>> print(*flatten(lst))
[[...]]
>>> lst.append(0)
>>> print(*flatten(lst))
[[...], 0]
>>> print(*list(flatten(lst))[0])
[[...], 0] 0
आप देख सकते हैं, यह इसी तरह 1 ('a',) bc
करने के साथ ही अपने स्वयं के विशेष तरीके से के रूप में विफल रहता है:
def flattish(*i):
for item in i:
try: iter(item)
except: yield item
else:
if isinstance(item, str): yield item
else: yield from flattish(*item)
class Fake:
def __init__(self, l):
self.l = l
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index >= len(self.l):
raise StopIteration
else:
self.index +=1
return self.l[self.index-1]
def __str__(self):
return str(self.l)
def flatten_notype(*i):
for item in i:
try:
n = next(iter(item))
try:
n2 = next(iter(n))
recur = n == n2
except TypeError:
yield from flatten(*item)
else:
if recur:
yield item
else:
yield from flatten(*item)
except TypeError:
yield item
def flatten(*i):
for item in i:
try:
n = next(iter(item))
try:
n2 = next(iter(n))
recur = n == n2
except TypeError:
yield from flatten(*item)
else:
if recur:
yield item if isinstance(n2, type(item)) or isinstance(item, type(n2)) else n2
else:
yield from flatten(*item)
except TypeError:
yield item
f = Fake('abc')
print(*flattish(f)) # should be `abc`
print(*flattish((f,))) # should be `abc` > ``
print(*flattish(1, ('a',), ('bc',))) # should be `1 a bc`
f = Fake([1, 2, 3])
print(*flattish(f)) # should be `1 2 3`
print(*flattish((f,))) # should be `1 2 3` > ``
print(*flattish(1, ('a',), ('bc',))) # should be `1 a bc`
f = Fake('abc')
print(*flatten_notype(f)) # should be `abc`
print(*flatten_notype((f,))) # should be `abc` > `c`
print(*flatten_notype(1, ('a',), ('bc',))) # should be `1 a bc` > `1 ('a',) bc`
f = Fake([1, 2, 3])
print(*flatten_notype(f)) # should be `1 2 3` > `2 3`
print(*flatten_notype((f,))) # should be `1 2 3` > ``
print(*flatten_notype(1, ('a',), ('bc',))) # should be `1 a bc` > `1 ('a',) bc`
f = Fake('abc')
print(*flatten(f)) # should be `abc` > `a`
print(*flatten((f,))) # should be `abc` > `c`
print(*flatten(1, ('a',), ('bc',))) # should be `1 a bc`
f = Fake([1, 2, 3])
print(*flatten(f)) # should be `1 2 3` > `2 3`
print(*flatten((f,))) # should be `1 2 3` > ``
print(*flatten(1, ('a',), ('bc',))) # should be `1 a bc`
मैं भी पुनरावर्ती lst
ऊपर परिभाषित और flatten()
साथ निम्नलिखित की कोशिश की है।
मैं how can python function access its own attributes? पढ़ सोच के हर वस्तु यह देखा था कि शायद समारोह ट्रैक रखने के सकता है, लेकिन वह काम नहीं होगा क्योंकि या तो हमारे lst
पहचान और समानता मिलान के साथ एक वस्तु है, तार वस्तुओं है कि केवल मिलान समानता हो सकती है शामिल , और flatten([1, 2], [1, 2])
जैसे कुछ की संभावना के कारण समानता पर्याप्त नहीं है।
क्या कोई विश्वसनीय तरीका है (यानी ज्ञात प्रकारों की जांच नहीं करता है, यह आवश्यक नहीं है कि एक कंटेनर कंटेनर और उसके कंटेनर सभी एक ही प्रकार के हों, आदि) यह जांचने के लिए कि एक कंटेनर संभावित क्षमता वाले वस्तुओं को रखता है या नहीं अनंत रिकर्सन, और विश्वसनीय रूप से सबसे छोटा अद्वितीय कंटेनर निर्धारित करते हैं? यदि ऐसा है, तो कृपया समझाएं कि यह कैसे किया जा सकता है, यह विश्वसनीय क्यों है, और यह विभिन्न पुनरावर्ती परिस्थितियों को कैसे संभालता है। यदि नहीं, तो कृपया समझाएं कि यह तर्कसंगत क्यों असंभव है।
मुझे लगता है कि निर्देशित ग्राफ में चक्रों का पता लगाने के लिए इसे कम किया जा सकता है। तो वहां लागू होने वाले सभी समाधानों को यहां लागू होना चाहिए .: http://stackoverflow.com/questions/261573/best-algorithm-for-detecting-cycles-in-a- प्रत्यक्ष- अनुच्छेद –