📜 ⬆️ ⬇️

Python: things you might not know

Python is a beautiful and sometimes mysterious language. And even knowing it very well, sooner or later you find something for yourself that you have not used before. This post reflects some of the details of the language, which many do not pay attention. I must say: many examples are impractical, but, therefore, no less interesting. Also, many examples demonstrate an unpythonic style, but I do not pretend to new standards - I just want to show what can be done like this.

1. Infinitely nested list

>>> a = [1, 2, 3, 4] >>> a.append(a) >>> a [1, 2, 3, 4, [...]] >>> a[4] [1, 2, 3, 4, [...]] >>> a[4][4][4][4][4][4][4][4][4][4] == a True 

The same with dictionaries:
 >>> a = {} >>> b = {} >>> a['b'] = b >>> b['a'] = a >>> print a {'b': {'a': {...}}} 


2. Formatting the list
')
 >>> l = [[1, 2, 3], [4, 5], [6], [7, 8, 9]] >>> sum(l, []) [1, 2, 3, 4, 5, 6, 7, 8, 9] 

List generator ( thanks to magic4x ):
 [y for x in data for y in x] 

Alternative, but longer options ( thanks monolithed ):
 import itertools data = [[1, 2, 3], [4, 5, 6]] list(itertools.chain.from_iterable(data)) 

 from functools import reduce from operator import add data = [[1, 2, 3], [4, 5, 6]] reduce(add, data) 


3. Dictionary Generator

Many people know about the list generator, but what about dictionary generators?
 >>> {a:a**2 for a in range(1, 10)} {1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81} 


4. Disposable function in class

In case you need a function that will be used only once, after which another function will be used:
 class foo: def normal_call(self): print("normal_call") def call(self): print("first_call") self.call = self.normal_call 

 >>> y = foo() >>> y.call() first_call >>> y.call() normal_call >>> y.call() normal_call 


5. Getting Class Attributes

 class GetAttr(object): def __getattribute__(self, name): f = lambda: "Hello {}".format(name) return f 

 >>> g = GetAttr() >>> g.Mark() 'Hello Mark' 


6. Set operations

Set - a set in which there are no duplicate elements:
 >>> a = set([1,2,3,4]) >>> b = set([3,4,5,6]) >>> a | b #  {1, 2, 3, 4, 5, 6} >>> a & b #  {3, 4} >>> a < b #  False >>> a - b #  {1, 2} >>> a ^ b #   {1, 2, 5, 6} 

Without a set set, these operations will not work. Unless it's a set generator ( thanks to ZyXI ):
 { x for x in range(10)} #   set([1, 2, 3]) == {1, 2, 3} set((i*2 for i in range(10))) == {i*2 for i in range(10)} 


7. Comparison operators

 >>> x = 5 >>> 1 < x < 10 True >>> 10 < x < 20 False >>> x < 10 < x*10 < 100 True >>> 10 > x <= 9 True >>> 5 == x > 4 True 


8. Dynamic creation of new classes

 >>> NewType = type("NewType", (object,), {"x": "hello"}) >>> n = NewType() >>> nx 'hello' 

The same option in its usual form:
 >>> class NewType(object): >>> x = "hello" >>> n = NewType() >>> nx "hello" 


9. Suppression of the "KeyError" exception in dictionaries

In the dictionaries there is a method .get () . In the usual case, if you call a non-existent key name_dict ['key'] , you will get a KeyError exception. However, if you call the key through the d.get method ('key') , then there will be no exception and, if there is no key, the dictionary will return None. If you want to assign a variable instead of a missing key, then you can assign a second parameter: d.get ('key', 0) .

This is best used when iterating over numeric keys:
 sum[value] = sum.get(value, 0) + 1 


10. Adding to the list in the dictionary

If you need to store several key values, you can store them in the list:

 >>> d = {} >>> a, b = 4, 5 >>> d[a] = list() >>> d {4: []} >>> d[a].append(b) >>> d {4: [5]} 


11. Assigning variables by condition

 x = 1 if (y == 10) else 2 # X  1,  ,  Y  10.     - X  2 x = 3 if (y == 1) else 2 if (y == -1) else 1 #   .    elif 


12. Unpacking Values ​​to Variables

If there are more variables when assigning their values, add an asterisk to the beginning of the variable name and the rest of the variables will be assigned to it (Python 3.x only):
 >>> first,second,*rest = (1,2,3,4,5,6,7,8) >>> first #   1 >>> second #   2 >>> rest #    [3, 4, 5, 6, 7, 8] 

 >>> first,*rest,last = (1,2,3,4,5,6,7,8) >>> first 1 >>> rest [2, 3, 4, 5, 6, 7] >>> last 8 


13. Numbering of elements of the list

 >>> l = ["spam", "ham", "eggs"] >>> list(enumerate(l)) >>> [(0, "spam"), (1, "ham"), (2, "eggs")] >>> list(enumerate(l, 1)) #        >>> [(1, "spam"), (2, "ham"), (3, "eggs")] 


14. Using else in exceptions

Thanks for fixing animeshneG
 try: function() except Error: #    try    Error else: #   try    except finally: #     


15. Making a copy of the list

When creating a copy using the usual method, the following will occur:
 >>> x = [1, 2, 3] >>> y = x >>> y[2] = 5 >>> y [1, 2, 5] >>> x [1, 2, 5] 

The correct option is:
 >>> x = [1,2,3] >>> y = x[:] >>> y.pop() 3 >>> y [1, 2] >>> x [1, 2, 3] 

Copying nested lists / dictionaries ( thanks to denisbalyko )
 import copy my_dict = {'a': [1, 2, 3], 'b': [4, 5, 6]} my_copy_dict = copy.deepcopy(my_dict) 


16. Numbering in for

For numbering elements when output through a for loop, use the enumerate method.
 >>> l = ['a', 'b', 'c', 'd', 'e'] >>> for i, value_list in enumerate(l, 1): #  1 -   >>> print(i, value_list) ... 1 a 2 b 3 c 4 d 5 e 


17. Default Function Values

If you assign incorrect arguments to functions by default, you might get something like this:
 >>> def foo(x=[]): ... x.append(1) ... print x ... >>> foo() [1] >>> foo() [1, 1] #    [1] >>> foo() [1, 1, 1] 


Instead, set the argument to None by default:
 >>> def foo(x=None): ... if x is None: ... x = [] ... x.append(1) ... print x >>> foo() [1] >>> foo() [1] 


18. __missing__ method for dictionaries

The __missing__ method eliminates the KeyError exception by returning the name of the requested key instead of an error.
 class MyDict(dict): #    def __missing__(self, key): return key ... >>> m = MyDict(a=1, b=2, c=3) #     >>> m {'a': 1, 'c': 3, 'b': 2} >>> m['a'] #     1 1 >>> m['z'] #         'z' 


19. Decorators

Decorators allow you to wrap one function by another, adding functionality to it. To denote the decorator on the line above the function, you write the character "@" and the name of the function. Example:
 >>> def print_args(function): >>> def wrapper(*args, **kwargs): >>> print ' : ', args, kwargs >>> return function(*args, **kwargs) >>> return wrapper >>> @print_args >>> def write(text): >>> print text >>> write('foo') Arguments: ('foo',) {} foo 

Only documentation can explain more simply:
 @f1(arg) @f2 def func(): pass 

equivalent to code
 def func(): pass func = f1(arg)(f2(func)) 


20. Exchange of values ​​between variables

 >>> a = 10 >>> b = 5 >>> a, b (10, 5) >>> a, b = b, a >>> a, b (5, 10) 


21. First class functions

 >>> def jim(phrase): ... return 'Jim says, "%s".' % phrase >>> def say_something(person, phrase): ... print person(phrase) >>> say_something(jim, 'hey guys') #     'Jim says, "hey guys".' 


Higher order functions ( thanks to Andrey_Solomatin ):
 #      g(),       . #       "100" (  (7+3)×(7+3)). def f(x): return x + 3 def g(function, x): return function(x) * function(x) print g(f, 7) 


22. Negative round

 >>> round(1234.5678, -2) 1200.0 >>> round(1234.5678, 2) 1234.57 


23. Python Zen

 import this 


24. Using style C ie {} instead of indents

This is probably evil, but if you want to use {} brackets instead of indents, to denote areas:
 from __future__ import braces 


25. Step in the cut list

 a = [1,2,3,4,5] >>> a[::2] #   [1,3,5] 

A value of -1 is equivalent to the reverse method — it reverses the list:
 >>> a[::-1] #   [5,4,3,2,1] 


26. Opening tabs in the browser

Opens a tab with the specified address in the default browser.
 import webbrowser webbrowser.open_new_tab('http://habrahabr.ru/') #  True    


27. zip . Merge lists

 a = [(1,2), (3,4), (5,6)] zip(*a) # [(1, 3, 5), (2, 4, 6)] 

Merging two lists into a dictionary:
 >>> t1 = (1, 2, 3) >>> t2 = (4, 5, 6) >>> dict (zip(t1,t2)) {1: 4, 2: 5, 3: 6} 


28. Sections in lists and work with them.

 >>> a = range(10) >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> a[:5] = [42] #    5   "42" >>> a [42, 5, 6, 7, 8, 9] >>> a[:1] = range(5) >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> del a[::2] #     >>> a [1, 3, 5, 7, 9] >>> a[::2] = a[::-2] #  reserved >>> a [9, 3, 5, 7, 1] 


29. Storing multiple items in the dictionary key

If you need to assign more than one element to the key, it is better to keep them in the list:
 >>> m = {} >>> m.setdefault('foo', []).append(1) >>> m {'foo': [1]} >>> m.setdefault('foo', []).append(2) >>> m {'foo': [1, 2]} 


30. Last and most important
For the sake of all the unknown, read the DOCUMENTATION ! Do not collect another bike - maybe your code is still someone read. No book will be able to reflect the completeness of the documentation, and the documentation in Python is excellent.


UPD:
31. @ Alex222 | comment
 import antigravity 


32. tanenn | comment
Using else in the for loop:
 >>> for n in range(2, 10): ... for x in range(2, n): ... if n % x == 0: ... print n, 'equals', x, '*', n/x ... break ... else: ... # loop fell through without finding a factor ... print n, 'is a prime number' 


33. monolithed | comment
Writing the first program - "Hello World!"
 import __hello__ 


34. AndersonDunai | comment
OrderedDict or dictionary sorting:
 >>> #    >>> d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2} >>> #     >>> OrderedDict(sorted(d.items(), key=lambda t: t[0])) OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)]) >>> #    >>> OrderedDict(sorted(d.items(), key=lambda t: t[1])) OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)]) >>> #      >>> OrderedDict(sorted(d.items(), key=lambda t: len(t[0]))) OrderedDict([('pear', 1), ('apple', 4), ('orange', 2), ('banana', 3)]) 


35. AndersonDunai | comment
Changing the class of an object on the fly from inside the class through self .__ class__ ( more )
Case in point ( thanks to dmitriko ):
 class Worm: def creep(self): print("i am creeping") class Butterfly: def fly(self): print("i am flying") creature = Worm() creature.creep() creature.__class__ = Butterfly creature.fly() 


36. skovorodkin | comment
Counting the number of elements (in the example - the number of letters in the word):
 from collections import Counter Counter('habrahabr') # Counter({'a': 3, 'h': 2, 'r': 2, 'b': 2}) 


37. assert
Assert is a special construct that allows you to check assumptions about the values ​​of arbitrary data in an arbitrary place in the program. This construct is used for testing / debugging code, for example, you can write such an instruction:
 assert x>y 

and if this instruction returns false, the Dissertation DescriptionError is raised. In essence, this instruction
 assert <test>, <data> 

this brief equivalent is:
  if __debug__: if not <test>: raise AssertationError, <data> 



Save the page with comments in pdf
If you have Google Chrome - just click Print -> Printer "Save as PDF". About a similar feature in other browsers - I do not know.

If you do not have Chrome
doPDF cuts the habr menu, and leaves comments. The Habra page is designed to be printed without a menu, so any virtual printer will do. As a result, we have a readable PDF file. Very comfortably. Download, install instead of the printer and send to print. (then another thank you say).

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


All Articles