Skip to main content

Return the first true value of an iterable.

Project description

first: The function you always missed in Python

first is a MIT licensed Python package with a simple function that returns the first true value from an iterable, or None if there is none. If you need more power, you can also supply a key function that is used to judge the truth value of the element or a default value if None doesn’t fit your use case.

I’m using the term “true” consistently with Python docs for any() and all() — it means that the value evaluates to true like: True, 1, "foo" or [None]. But not: None, False or 0. In JavaScript, they call this “truthy”.

Examples

A simple example to get started:

>>> from first import first
>>> first([0, None, False, [], (), 42])
42

However, it’s especially useful for dealing with regular expressions in if/elif/else branches:

import re

from first import first


re1 = re.compile('b(.*)')
re2 = re.compile('a(.*)')

m = first(regexp.match('abc') for regexp in [re1, re2])
if not m:
   print('no match!')
elif m.re is re1:
   print('re1', m.group(1))
elif m.re is re2:
   print('re2', m.group(1))

The optional key function gives you even more selection power. If you want to return the first even number from a list, just do the following:

>>> from first import first
>>> first([1, 1, 3, 4, 5], key=lambda x: x % 2 == 0)
4

default on the other hand allows you to specify a value that is returned if none of the elements is true:

>>> from first import first
>>> first([0, None, False, [], ()], default=42)
42

Usage

The package consists of one module consisting of one function:

from first import first

first(iterable, default=None, key=None)

This function returns the first element of iterable that is true if key is None. If there is no true element, the value of default is returned, which is None by default.

If a callable is supplied in key, the result of key(element) is used to judge the truth value of the element, but the element itself is returned.

first has no dependencies and should work with any Python available. Of course, it works with the awesome Python 3 everybody should be using.

Alternatives

first brings nothing to the table that wasn’t possible before. However the existing solutions aren’t very idiomatic for such a common and simple problem.

The following constructs are equivalent to first(seq) and work since Python 2.6:

next(itertools.ifilter(None, seq), None)
next(itertools.ifilter(bool, seq), None)
next((x for x in seq if x), None)

None of them is as pretty as I’d like them to be. The re example from above would look like the following:

next(itertools.ifilter(None, (regexp.match('abc') for regexp in [re1, re2])), None)
next((regexp.match('abc') for regexp in [re1, re2] if regexp.match('abc')), None)

Note that in the second case you have to call regexp.match() twice. For comparison, one more time the first-version:

first(regexp.match('abc') for regexp in [re1, re2])

Idiomatic, clear and readable. Pythonic. :)

Background

The idea for first goes back to a discussion I had with Łukasz Langa about how the re example above is painful in Python. We figured such a function is missing Python, however it’s rather unlikely we’d get it in and even if, it wouldn’t get in before 3.4 anyway, which is years away as of yours truly is writing this.

So I decided to release it as a package for now. If it proves popular enough, it may even make it into Python’s stdlib in the end.

History

2.0.0 (2012-10-13)

  • pred proved to be rather useless. Changed to key which is just a selector. This is a backward incompatible change and the reason for going 2.0.

  • Add default argument which is returned instead of None if no true element is found.

1.0.2 (2012-10-09)

  • Fix packaging. I get this never right the first time. :-/

1.0.1 (2012-10-09)

  • Documentation fixes only.

1.0.0 (2012-10-09)

  • Initial release.

Credits

“first” is written and maintained by Hynek Schlawack and various contributors:

  • Łukasz Langa

  • Nick Coghlan

  • Vincent Driessen

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

first-2.0.0.tar.gz (4.9 kB view details)

Uploaded Source

Built Distribution

first-2.0.0-py2.py3-none-any.whl (7.0 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file first-2.0.0.tar.gz.

File metadata

  • Download URL: first-2.0.0.tar.gz
  • Upload date:
  • Size: 4.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for first-2.0.0.tar.gz
Algorithm Hash digest
SHA256 c5711941f8ba8b091e73713eb0b45ddab663c060de324973b4cdd2290a1524ec
MD5 894015e227d749f9f02b43b6d337cc3c
BLAKE2b-256 91f07c4090ee35ead6e17c46b83ec04e354de42d1ff5e00876fc1c26c793e3b7

See more details on using hashes here.

File details

Details for the file first-2.0.0-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for first-2.0.0-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 7ce8c2d25d2f7f54ad6d8a725df71e7a35ae11052d41cbeafcd19f71661a1107
MD5 60371c229be08f41aa7730fa597f814e
BLAKE2b-256 848f0d29d3e62d00b3c3f30371eb3f606add18181794343fd516b063501c2880

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page