python list generator comprehention - ghdrako/doc_snipets GitHub Wiki

iteration comprehension instance
[expression for item in iterable ] [] list
{key_expr : value_expr for item in iterable } {:} dict
{expression for item in iterable } {} set
(expression for item in iterable) () generator

Comprehension is not always the best option.

  • First if you don’t need to manipulate the items in the iterable, you should consider using their constructors directly. In example convert list: numbers = [1, 1, 2, 3] to set. You an use set comprehension: {x for x in numbers} but better option is use constructor ''set(numbers)''

  • Second, when the comprehension requires complicated expressions or deeply nested for loops, it’s better to use the conventional for-loop approach.

list comprehention

Wyrazenia listowe moga byc uzyte tylko do budowy list

cartesian product

colors = ['black,'white']
size = ['S','M','L']
tishorts=[(color,size) for color in colors 
                       for size in sizes]

count elements

total_employees = len(employees)
total_parttime_employees = len([employee for employee in employees if employee.part_time]) 
total_managers = sum([employee for employee in employees if employee.manager])

# using sum and generator
total_parttime_employees = sum(employee for employee in employees if employee.part_time) 
total_managers = sum(employee for employee in employees if employee.manager)

generator comprehention

symbols='$#@!'
tuple(ord(symbol) for symbol in symbols)

import array
array.array('I',(ord(symbol) for symbol in symbols))  # pierwszy argument definjuje typ do przechowywania
numbers = [1, 2, 3]
numbers_gen = (x*x for x in numbers)
print(type(numbers_gen))
# output: <class 'generator'>

You can't use len() with a generator expression, but you can use sum():

>>> len(1 for x in range(20) if x > 8)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'generator' has no len()
>>> sum(1 for x in range(20) if x > 8)
11

pass a generator expression to sum() which avoids having to create a temporary list, the sum() idiom also works when you don't necessarily want every item in the sequence to be counted.

sum(c.isupper() for c in 'Hello, WORLD')
sum(len(s) > 3 for s in 'a bb ccc d eeee ff gggg'.split())

You can implement these with list comprehensions too, but it just feels clunky, and of course there's that wasted memory and wasted time of creating a list that isn't needed:

len([c for c in 'Hello, WORLD' if c.isupper()])
len([s for s in 'a bb ccc d eeee ff gggg'.split() if len(s) > 3])

flatten nested list

flattened_items0 = []
for task in tasks:
  for item in task:
    flattened_items0.append(item)
assert flattened_items0 == ['Homework', 'Physics and math', 5, 'Laundry', 'Wash clothes', 3, 'Museum', 'Egypt exhibit', 4]
flattened_items1 = [item for task in tasks for item in task]  # outer loop: for task in tasks inner loop: for item in task and output element item
assert flattened_items0 == flattened_items1

In this code, the first for loop extracts each task from the list object tasks , and the second for loop extracts each item of the task object. The first for refers to the outer one, and the second for refers to the inner one:

[expression for iterable in iterables for item in iterable] 

3 level

styles = ['long-sleeve', 'v-neck']
colors = ['white', 'black']
sizes = ['L', 'S']
options = [' '.join([style, color, size]) for style in styles for color in colors for size in sizes]

in this case more readableis

options = []
for style in styles:
  for color in colors:
    for size in sizes:
      option = ' '.join([style, color, size])
      options.append(option)

Applying a filtering condition

filtered_titles0 = []
for task in tasks:
  if task.urgency > 3:
    filtered_titles0.append(task.title)
assert filtered_titles0 == ['Homework', 'Museum']
filtered_titles1 = [task.title for task in tasks if task.urgency > 3]
assert filtered_titles0 == filtered_titles1
list_odd = [] # start from an empty list
for i in range(1, 21):
  if i%2 !=0:
    list_odd.append(i**2)
list_odd_lc = [i**2 for i in range(1, 21) if i%2 !=0]

Dict comprehension

title_dict0 = {}
for task in tasks:
  title_dict0[task.title] = task.description

title_dict1 = {task.title: task.description for task in tasks}
assert title_dict0 == title_dict1

Set comprehention

title_set0 = set() # Creating an empty set requires a set constructor, as there is no literal form for an empty set.
for task in tasks:
  title_set0.add(task.title)

title_set1 = {task.title for task in tasks}
assert title_set0 == title_set1 == {'Homework', 'Laundry', 'Museum'}
⚠️ **GitHub.com Fallback** ⚠️