Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #90537

Re: itertools py3.4 - filter list using not equal - fails as bool

Path csiph.com!usenet.pasdenom.info!news.redatomik.org!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail
Return-Path <python-python-list@m.gmane.org>
X-Original-To python-list@python.org
Delivered-To python-list@mail.python.org
X-Spam-Status OK 0.000
X-Spam-Evidence '*H*': 1.00; '*S*': 0.00; 'subject:not': 0.03; 'else:': 0.03; 'elif': 0.05; '(python': 0.07; 'ugly': 0.07; '3),': 0.09; '[1,': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'subject:using': 0.09; 'def': 0.12; '(1,': 0.16; '(2,': 0.16; '(3,': 0.16; '(converted': 0.16; '1),': 0.16; '12)': 0.16; '2),': 0.16; '3)]': 0.16; '4),': 0.16; '5),': 0.16; '[2,': 0.16; 'argument.': 0.16; 'collections': 0.16; 'evaluates': 0.16; 'item:': 0.16; 'item[0]': 0.16; 'itertools': 0.16; 'received:80.91.229.3': 0.16; 'received:dip0.t-ipconnect.de': 0.16; 'received:plane.gmane.org': 0.16; 'received:t-ipconnect.de': 0.16; 'sequence:': 0.16; 'stats': 0.16; 'subject:fails': 0.16; 'true:': 0.16; 'wrote:': 0.18; 'bit': 0.19; '>>>': 0.22; 'example': 0.22; 'import': 0.22; 'header:User-Agent:1': 0.23; 'example.': 0.24; 'skip:l 30': 0.24; 'pass': 0.26; 'header:X -Complaints-To:1': 0.27; 'function': 0.29; 'subject:list': 0.30; 'tuples': 0.31; 'summary': 0.32; 'url:python': 0.33; 'beginning': 0.33; 'could': 0.34; "can't": 0.35; 'created': 0.35; 'but': 0.35; 'sequence': 0.36; 'url:org': 0.36; 'list': 0.37; 'easily': 0.37; 'filter': 0.38; 'url:library': 0.38; 'to:addr:python-list': 0.38; '12,': 0.39; 'to:addr:python.org': 0.39; 'received:org': 0.40; 'how': 0.40; 'easy': 0.60; 'url:3': 0.61; 'simply': 0.61; 'first': 0.61; 'become': 0.64; 'more': 0.64; 'total': 0.65; 'hoping': 0.75; 'demonstrates': 0.84; 'total,': 0.84
X-Injected-Via-Gmane http://gmane.org/
To python-list@python.org
From Peter Otten <__peter__@web.de>
Subject Re: itertools py3.4 - filter list using not equal - fails as bool
Date Wed, 13 May 2015 09:40:05 +0200
Organization None
References <05defef5-74aa-4a5d-b7e7-9b521512152c@googlegroups.com>
Mime-Version 1.0
Content-Type text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding 7Bit
X-Gmane-NNTP-Posting-Host p57bd9b5c.dip0.t-ipconnect.de
User-Agent KNode/4.13.3
X-BeenThere python-list@python.org
X-Mailman-Version 2.1.20+
Precedence list
List-Id General discussion list for the Python programming language <python-list.python.org>
List-Unsubscribe <https://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list/>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <https://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
Newsgroups comp.lang.python
Message-ID <mailman.435.1431502814.12865.python-list@python.org> (permalink)
Lines 112
NNTP-Posting-Host 2001:888:2000:d::a6
X-Trace 1431502814 news.xs4all.nl 2938 [2001:888:2000:d::a6]:48233
X-Complaints-To abuse@xs4all.nl
Xref csiph.com comp.lang.python:90537

Show key headers only | View raw


Sayth Renshaw wrote:

> why can't I filter a list based on an itertools condition using dropwhile?
> 
> This is the docs and the example.
> https://docs.python.org/3/library/itertools.html#itertools.dropwhile
> 
> def less_than_10(x):
>     return x < 10
> 
> itertools.takewhile(less_than_10, itertools.count()) =>
>   0, 1, 2, 3, 4, 5, 6, 7, 8, 9

As the example demonstrates dropwhile() takes a function as its first 
argument. To apply it to a sequence of tuples you could write

>>> items
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
>>> def first_is_one(t):
...     return t[0] == 1
... 
>>> list(itertools.dropwhile(first_is_one, items))
[(2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]

However, if not all items where the predicate function evaluates to True are 
at the beginning of the sequence:

>>> def second_is_one(t):
...     return t[1] == 1
... 
>>> list(itertools.dropwhile(second_is_one, items))
[(1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]

If you want only the items where t[1] != 1 you need filter() or 
itertools.filterfalse() (Python 2: itertools.ifilter or 
itertools.ifilterfalse)

>>> list(itertools.filterfalse(second_is_one, items))
[(1, 2), (1, 3), (2, 2), (2, 3), (3, 2), (3, 3)]

> so I have a list I have created (converted from itertools). pm is
> permutations
> 
> 
> print(stats)
> [(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 2), (1, 3, 4), (1, 3, 5), (1, 4,
> [2), (1, 4, 3), (1, 4, 5), (1, 5, 2), (1, 5, 3), (1, 5, 4), (2, 1, 3), (2,
> [1, 4), (2, 1, 5), (2, 3, 1), (2, 3, 4), (2, 3, 5), (2, 4, 1), (2, 4, 3),
> [(2, 4, 5), (2, 5, 1), (2, 5, 3), (2, 5, 4), (3, 1, 2), (3, 1, 4), (3, 1,
> [5), (3, 2, 1), (3, 2, 4), (3, 2, 5), (3, 4, 1), (3, 4, 2), (3, 4, 5), (3,
> [5, 1), (3, 5, 2), (3, 5, 4), (4, 1, 2), (4, 1, 3), (4, 1, 5), (4, 2, 1),
> [(4, 2, 3), (4, 2, 5), (4, 3, 1), (4, 3, 2), (4, 3, 5), (4, 5, 1), (4, 5,
> [2), (4, 5, 3), (5, 1, 2), (5, 1, 3), (5, 1, 4), (5, 2, 1), (5, 2, 3), (5,
> [2, 4), (5, 3, 1), (5, 3, 2), (5, 3, 4), (5, 4, 1), (5, 4, 2), (5, 4, 3)]
> 
> 
> I simply wanted to create an easy way to create summary stats of my stats
> list(poorly named). So in this case easy to check answers. so how many
> tuples in my list have a 1 in item[0] and how many don't. Then hoping to
> build on that for example how many have item[0] == 1 && (item[1] == 2 or
> item[1] == 4) etc.
> 
> I can achieve it via an else if but that would become ugly quick.
> 
> for item in stats:
>     if item[0] == 1:
>         nums += 1
>     elif item[0] != 1:
>         not_in += 1
>     else:
>         pass

Why would this become ugly? You can reshuffle it a bit to make it more 
general:

>>> def count(items):
...     t = f = 0
...     for item in items:
...         if item:
...             t += 1
...         else:
...             f += 1
...     return f, t
... 
>>> count(t[1] == 1 for t in stats)
(48, 12)
>>> count(t[0] == 1 for t in stats)
(48, 12)
>>> count(t[0] in (1, 2) for t in stats)
(36, 24)
>>> count(sum(t) == 6 for t in stats)
(54, 6)

Alternatively collections.Counter() supports an arbitrary number of bins...

>>> import collections
>>> freq = collections.Counter(t[1] for t in stats)
>>> freq
Counter({1: 12, 2: 12, 3: 12, 4: 12, 5: 12})

...but you can easily reduce them:

>>> freq = collections.Counter(t[1] == 1 for t in stats)
>>> freq
Counter({False: 48, True: 12})
>>> one = freq[True]
>>> total = sum(freq.values())
>>> print("{} of {} ({}%) have t[1] == 1".format(one, total, one/total*100))
12 of 60 (20.0%) have t[1] == 1


Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

itertools py3.4 - filter list using not equal - fails as bool Sayth Renshaw <flebber.crue@gmail.com> - 2015-05-12 15:43 -0700
  Re: itertools py3.4 - filter list using not equal - fails as bool MRAB <python@mrabarnett.plus.com> - 2015-05-13 00:22 +0100
  Re: itertools py3.4 - filter list using not equal - fails as bool Peter Otten <__peter__@web.de> - 2015-05-13 09:40 +0200
    Re: itertools py3.4 - filter list using not equal - fails as bool Sayth Renshaw <flebber.crue@gmail.com> - 2015-05-13 06:58 -0700

csiph-web