Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #64012
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Subject | Re: Chanelling Guido - dict subclasses |
| Date | 2014-01-15 19:35 +0100 |
| Organization | None |
| References | <52d5e408$0$29970$c3e8da3$5496439d@news.astraweb.com> <mailman.5494.1389775244.18130.python-list@python.org> <05ff1332-1776-4ac0-88b4-84f8fd323ce3@googlegroups.com> |
| Newsgroups | comp.lang.python |
| Message-ID | <mailman.5540.1389810978.18130.python-list@python.org> (permalink) |
John Ladasky wrote:
> On Wednesday, January 15, 2014 12:40:33 AM UTC-8, Peter Otten wrote:
>> Personally I feel dirty whenever I write Python code that defeats duck-
>> typing -- so I would not /recommend/ any isinstance() check.
>
> While I am inclined to agree, I have yet to see a solution to the problem
> of flattening nested lists/tuples which avoids isinstance(). If anyone
> has written one, I would like to see it, and consider its merits.
Well, you should always be able to find some property that discriminates
what you want to treat as sequences from what you want to treat as atoms.
(flatten() Adapted from a nine-year-old post by Nick Craig-Wood
<https://mail.python.org/pipermail/python-list/2004-December/288112.html>)
>>> def flatten(items, check):
... if check(items):
... for item in items:
... yield from flatten(item, check)
... else:
... yield items
...
>>> items = [1, 2, (3, 4), [5, [6, (7,)]]]
>>> print(list(flatten(items, check=lambda o: hasattr(o, "sort"))))
[1, 2, (3, 4), 5, 6, (7,)]
>>> print(list(flatten(items, check=lambda o: hasattr(o, "count"))))
[1, 2, 3, 4, 5, 6, 7]
The approach can of course break
>>> items = ["foo", 1, 2, (3, 4), [5, [6, (7,)]]]
>>> print(list(flatten(items, check=lambda o: hasattr(o, "count"))))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 4, in flatten
File "<stdin>", line 4, in flatten
File "<stdin>", line 4, in flatten
File "<stdin>", line 4, in flatten
File "<stdin>", line 4, in flatten
File "<stdin>", line 4, in flatten
File "<stdin>", line 4, in flatten
File "<stdin>", line 2, in flatten
RuntimeError: maximum recursion depth exceeded
and I'm the first to admit that the fix below looks really odd:
>>> print(list(flatten(items, check=lambda o: hasattr(o, "count") and not
hasattr(o, "split"))))
['foo', 1, 2, 3, 4, 5, 6, 7]
In fact all of the following examples look more natural...
>>> print(list(flatten(items, check=lambda o: isinstance(o, list))))
['foo', 1, 2, (3, 4), 5, 6, (7,)]
>>> print(list(flatten(items, check=lambda o: isinstance(o, (list,
tuple)))))
['foo', 1, 2, 3, 4, 5, 6, 7]
>>> print(list(flatten(items, check=lambda o: isinstance(o, (list, tuple))
or (isinstance(o, str) and len(o) > 1))))
['f', 'o', 'o', 1, 2, 3, 4, 5, 6, 7]
... than the duck-typed variants because it doesn't matter for the problem
of flattening whether an object can be sorted or not. But in a real-world
application the "atoms" are more likely to have something in common that is
required for the problem at hand, and the check for it with
def check(obj):
return not (obj is an atom) # pseudo-code
may look more plausible.
Back to comp.lang.python | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Chanelling Guido - dict subclasses Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-01-15 01:27 +0000
Re: Chanelling Guido - dict subclasses Ned Batchelder <ned@nedbatchelder.com> - 2014-01-14 21:04 -0500
Re: Chanelling Guido - dict subclasses Terry Reedy <tjreedy@udel.edu> - 2014-01-14 22:48 -0500
Re: Chanelling Guido - dict subclasses F <f@hop2it.be> - 2014-01-15 07:00 +0000
Re: Chanelling Guido - dict subclasses Peter Otten <__peter__@web.de> - 2014-01-15 09:40 +0100
Re: Chanelling Guido - dict subclasses John Ladasky <john_ladasky@sbcglobal.net> - 2014-01-15 08:51 -0800
Re: Chanelling Guido - dict subclasses Peter Otten <__peter__@web.de> - 2014-01-15 19:35 +0100
Re: Chanelling Guido - dict subclasses Devin Jeanpierre <jeanpierreda@gmail.com> - 2014-01-15 22:30 -0800
Re: Chanelling Guido - dict subclasses Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-01-15 09:10 +0000
Re: Chanelling Guido - dict subclasses Tim Chase <python.list@tim.thechases.com> - 2014-01-15 05:03 -0600
Re: Chanelling Guido - dict subclasses Daniel da Silva <var.mail.daniel@gmail.com> - 2014-01-15 19:50 -0500
Re: Chanelling Guido - dict subclasses Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2014-01-16 17:17 +1300
csiph-web