📜 ⬆️ ⬇️

Python Tips, Tricks, and Hacks (Part 2)

Content

Lists. List rollout (reduce). Passing through the list (range, xrange and enumerate). Checking all list items for the condition (all and any). Grouping elements of several lists (zip). A few more operators to work with lists. Advanced logical operations with type set.
Dictionaries. Creating a dictionary using named arguments. Convert dictionary to list and back. Dictionary Comprehensions.

2 Lists


2.2 List folding

Unfortunately, you can not write a program only with the help of list generators. (I'm joking ... of course you can.) They can display and filter, but there is no easy way to convolve a list. By this concept, I mean applying the function to the first two elements of the list, and then to the resulting result and the next element, and so on until the end of the list. You can accomplish this through a for loop:
Copy Source | Copy HTML numbers = [1,2,3,4,5] result = 1 for number in numbers: result *= number # result = 120 

And you can use the built-in reduce function, which takes as its arguments a function from two parameters and a list:
 Copy Source | Copy HTML numbers = [1,2,3,4,5] result = reduce(lambda a,b: a*b, numbers) # result = 120 

Not as beautiful as list generators, but shorter than the usual loop. It is worth remembering this way.

2.3 Passing through the list: range, xrange and enumerate

Remember how in C for the for loop you used a counter variable instead of list items? You may already know how to simulate this behavior in Python using range and xrange. By passing the value value of the range function, we get a list containing elements from 0 to value-1 inclusive. In other words, range returns indexes of a list of the specified length. xrange works similar, but more efficiently, without loading the entire list into memory.
 Copy Source | Copy HTML strings = ['a', 'b', 'c', 'd', 'e'] for index in xrange(len(strings)): print index, #  "0 1 2 3 4" 

The problem is that you usually still need list items. What is the use of indices without them? Python has a terrific enumerate built-in function that provides an iterator for pairs of index → ​​value:
 Copy Source | Copy HTML strings = ['a', 'b', 'c', 'd', 'e'] for index, string in enumerate(strings): print index, string, #  "0 a 1 b 2 c 3 d 4 e" 

Another plus is that enumerate looks more readable than xrange (len ()). Therefore, range and xrange are probably useful only for creating a list from scratch, and not on the basis of other data.

2.4 Checking All List Items for a Condition

Suppose we need to check whether the condition is satisfied for at least one element. Before Python 2.5, you could write like this:
 Copy Source | Copy HTML numbers = [1,10,100,1000,10000] if [number for number in numbers if number < 10]: print 'At least one element is over 10' # : "At least one element is over 10" <source>        ,    ,   false.       ,    true.  ,     ,     ,  .             ,      Python 2.5,        .     any,   Python 2.5,         .  any    True,    ,  .    -,   True  False   ,     any.        ,  any    . <source> Copy Source | Copy HTML numbers = [1,10,100,1000,10000] if any(number < 10 for number in numbers): print 'Success' # : "Success!" 

Similarly, there may be a task to check that all elements satisfy the condition. Without Python 2.5 you have to write like this:
 Copy Source | Copy HTML numbers = [1,2,3,4,5,6,7,8,9] if len(numbers) == len([number for number in numbers if number < 10]): print 'Success!' # : "Success!" 

Here we filter the list and check if its length has decreased. If not, then all its elements satisfy the condition. Again, without Python 2.5, this is the only way to fit all the logic into one expression.
')
In Python 2.5, there is a simpler way - the all builtin function. It is easy to guess that it stops checking after the first element that does not satisfy the condition. This feature works exactly the same as the previous one.
 Copy Source | Copy HTML numbers = [1,2,3,4,5,6,7,8,9] if all(number < 10 for number in numbers): print 'Success!' # : "Success!" 

2.5 Grouping elements of several lists

The built-in zip function is used to compress several lists into one. It returns an array of tuples, with the nth tuple containing the nth elements of all arrays passed as arguments. This is the case when the example is the best explanation:
 Copy Source | Copy HTML letters = ['a', 'b', 'c'] numbers = [1, 2, 3] squares = [1, 4, 9] zipped_list = zip(letters, numbers, squares) # zipped_list = [('a', 1, 1), ('b', 2, 4), ('c', 3, 9)] 

This item is often used as an iterator for a for loop, extracting three values ​​in one iteration (“for letter, number, squares in zipped_list”).

2.6 A few more operators to work with lists

The following are built-in functions that take any iterable object as an argument.
max and min return the largest and smallest element respectively.
sum returns the sum of all the items in the list. The optional second parameter sets the initial amount (default is 0).

2.7 Advanced logical operations with type set.

I understand that in the section on lists, it’s not allowed to talk about sets. But while I did not use them, I lacked some logical operations in the lists. A set is different from the list in that its elements are unique and unordered. You can also perform many logical operations on sets.

A fairly common task is to make sure that the list items are unique. It's easy, just convert it to a set and check whether the length has changed:
 Copy Source | Copy HTML numbers = [1,2,3,3,4,1] set(numbers) #  set([1,2,3,4]) if len(numbers) == len(set(numbers)): print 'List is unique!' #    

Of course, you can convert the set back to the list, but do not forget that the order of the elements could not be preserved. More information about the operations with sets can be found in the documentation .

3 Dictionaries


3.1 Creating a Dictionary with Named Arguments

When I started learning Python, I completely missed an alternative way to create a dictionary. If you pass named arguments to the dict constructor, they will be added to the returned dictionary. Of course, the same restrictions apply to its keys as to variable names. Here is an example:
 Copy Source | Copy HTML dict(a=1, b=2, c=3) #  {'a': 1, 'b': 2, 'c': 3} 

This method clears the code a bit, saving you from flying quotes. I use it often.

3.2 Converting a dictionary to a list

To get a list of keys, simply cast the dictionary to the list type. But it is better to use .keys () to get a list of keys, or .iterkeys () to get an iterator. If you need values, use .values ​​() and .itervalues ​​(). But remember that the dictionaries are not ordered, so the values ​​obtained can be mixed in any conceivable way.

To get both keys and values ​​as a list of tuples, you can use .items () or .iteritems (). Perhaps you often used this exciting method:
 Copy Source | Copy HTML dictionary = {'a': 1, 'b': 2, 'c': 3} dict_as_list = dictionary.items() #dict_as_list = [('a', 1), ('b', 2), ('c', 3)] 

3.3 Converting a list to a dictionary

The inverse operation — turning a list containing key-value pairs into a dictionary — is also made easy:
 Copy Source | Copy HTML dict_as_list = [['a', 1], ['b', 2], ['c', 3]] dictionary = dict(dict_as_list) # dictionary = {'a': 1, 'b': 2, 'c': 3} 

You can combine methods by adding named arguments:
 Copy Source | Copy HTML dict_as_list = [['a', 1], ['b', 2], ['c', 3]] dictionary = dict(dict_as_list, d=4, e=5) # dictionary = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5} 

Turning lists and dictionaries into each other is quite convenient. But the next tip is awesome.

3.3 "Dictionary Comprehensions"

Although there is no built-in dictionary generator in Python, you can do something similar at the cost of a little clutter in the code. Use .iteritems () to turn the dictionary into a list, pass it to an expression generator or list generator, and then convert the list back to a dictionary.

Suppose we have a dictionary of pairs of name: email, and we want to get a dictionary of pairs of name: is_email_at_a_dot_com (check each address for the occurrence of the substring .com):
 Copy Source | Copy HTML emails = {'Dick': 'bob@example.com', 'Jane': 'jane@example.com', 'Stou': 'stou@example.net'} email_at_dotcom = dict( [name, '.com' in email] for name, email in emails.iteritems() ) # email_at_dotcom = {'Dick': True, 'Jane': True, 'Stou': False} 

Of course, it is not necessary to begin and end with a dictionary, in some places you can use lists.

This is a bit less readable than strict list generators, but I think it’s better than a large for loop.

Full article in PDF

Source: https://habr.com/ru/post/85459/


All Articles