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.
Wyrazenia listowe moga byc uzyte tylko do budowy list
colors = ['black,'white']
size = ['S','M','L']
tishorts=[(color,size) for color in colors
for size in sizes]
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)
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])
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)
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]
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
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'}