Code like a pythonista: idiomatic python (part1)

cycle(iterable)

Итератор cycle из itertools позволяет вам создавать итератор, которой создает бесконечный цикл ряда значений. Давайте передадим ему строку из трех букв и посмотрим, к чему это приведет:


Python

from itertools import cycle

count = 0 for item in cycle(‘XYZ’): if count > 7: break print(item) count += 1

1 2 3 4 5 6 7 8

fromitertoolsimportcycle

count=

foritem incycle(‘XYZ’)

ifcount>7

break

print(item)

count+=1

Результат:

Python

X Y Z X Y Z X Y

1 2 3 4 5 6 7 8

X Y Z X Y Z X Y

Здесь мы создаем цикл for для того, чтобы бесконечно зациклить буквы Z, Y, Z. Конечно, нам не нужен бесконечный цикл на постоянной основе, так что мы добавим простой счетчик для разрыва цикла. Вы также можете использовать встроенный инструмент Python под названием next для итерации над итераторами, которые вы создаете при помощи itertools:

Python

from itertools import cycle

polys = iterator = cycle(polys)

print(next(iterator)) # triangle print(next(iterator)) # square print(next(iterator)) # pentagon print(next(iterator)) # rectangle print(next(iterator)) # triangle print(next(iterator)) # square

1 2 3 4 5 6 7 8 9 10 11

fromitertoolsimportcycle

polys=’triangle’,’square’,’pentagon’,’rectangle’

iterator=cycle(polys)

print(next(iterator))# triangle

print(next(iterator))# square

print(next(iterator))# pentagon

print(next(iterator))# rectangle

print(next(iterator))# triangle

print(next(iterator))# square

В данном коде мы создаем простой список полигонов и передаем их циклу. Мы сохраняем наш новый итератор в качестве переменной, и затем мы передаем эту переменную нашей следующей функции. Каждый раз, когда мы вызываем функцию, она возвращает следующее значение в итераторе. Так как этот итератор бесконечный, мы можем вызывать next днями напролет, и все равно объекты никогда не закончатся.

EDIT 2

I searched a one-line method, with a list comprehension or a generator expression.

I found to ways of doing this, I think it isn’t possible to do without groupby()

Based on the same principle, it is easy to convert the function of dugres into a generator function:

However , this generator function has two disadvantages:

  • it resorts to the function groupby(), which is not easy to understand by someone not used to Python

  • its execution’s time is longer than the ones of my generator function treat() and the generator function of John Machin, that don’t use groupby().

I slightly modified them to make them able to accept a sequence of items to be de-duplicated, and I measured the durations of execution:

The instruction

is necessary to avoid errors when the the iterable argument is a sequence and the other argument only one string: this latter needs then to be modified into a container, provided that the iterable argument isn’t a string itself.


It is based on the fact that sequences like tuples, lists, stes… have the method iter, but strings haven’t. The following code shows the problems:

result

I obtained the following execution’s time:

I prefer the solution of John Machin because there is no instruction B = iter(B) as in mine.

But the instruction with appears weird to me. So I finally think the better solution is the following code, that works even with a string as iterable argument, and in which the first object previous being defined isn’t a fake:

starmap(function, iterable)

Инструмент starmap создает итератор, который может проводить вычисления, используя функцию и итерируемый. В документации отмечают следующее:

Давайте взглянем на простой пример:

Python

from itertools import starmap

def add(a, b): return a+b

for item in starmap(add, ): print(item)

1 2 3 4 5 6 7

fromitertoolsimportstarmap

defadd(a,b)

returna+b

foritem instarmap(add,(2,3),(4,5))

print(item)

Здесь мы создаем простую функцию добавления, которая принимает два аргумента. Далее мы создаем цикл for и вызываем starmap с функцию в его первом аргументе и списком кортежей для итерируемой. Функция starmap передает все объекты кортежей функции и возвращает итератор результатов, который мы выводим.

2) Duck-typed, EAFP style:

This shoot-first-ask-questions-last attitude is common in Python. Instead of testing in advance if the object is suitable, just carry out the operation and catch relevant Exceptions:

Off course the second except clause in the example above is not only of questionable humor but totally unnecessary (the point was to illustrate duck-typing for people not familiar with the concept).

If you expect multiple occurrences of thing:

  • a little verbose for this specific use case, but very idiomatic in Python.
  • this performs better than #1
  • PEP 463 proposed a shorter syntax for try/except simple usage that would be handy here, but it was not approved.

However, with (introduced in python 3.4) the above code can be simplified to this:

Again, if you expect multiple occurrences of thing:

Документация

Далее нужно проделать минимальные шаги для настройки:

Поэтому пришлось переписать его в формате . А если бы хоть раз дочитал до конца стартовый мануал, то понял, что умеет и в Markdown. Включаю файл в

  1. Добавляю папку с пакетом в . Это позволит делать импорты нашего кода для анализа.
  2. Добавляю папку и закидываю туда файл описания каждого модуля. Документация должна автомагически сгенерироваться из комментариев:

Использую команду явно, вместо , так как ее под Windows нет. А я не хочу нарушать принцип о кроссплатформенной разработке.

Как только сделанные изменения замержены, автоматически соберет документацию и опубликует.


И создаю специальный конфиг файл для , в котором описываю среду для запуска билда:

Снова добавляю бейдж:

Python NumPy

NumPy IntroNumPy Getting StartedNumPy Creating ArraysNumPy Array IndexingNumPy Array SlicingNumPy Data TypesNumPy Copy vs ViewNumPy Array ShapeNumPy Array ReshapeNumPy Array IteratingNumPy Array JoinNumPy Array SplitNumPy Array SearchNumPy Array SortNumPy Array FilterNumPy Random Random Intro Data Distribution Random Permutation Seaborn Module Normal Distribution Binomial Distribution Poisson Distribution Uniform Distribution Logistic Distribution Multinomial Distribution Exponential Distribution Chi Square Distribution Rayleigh Distribution Pareto Distribution Zipf Distribution

NumPy ufunc ufunc Intro ufunc Create Function ufunc Simple Arithmetic ufunc Rounding Decimals ufunc Logs ufunc Summations ufunc Products ufunc Differences ufunc Finding LCM ufunc Finding GCD ufunc Trigonometric ufunc Hyperbolic ufunc Set Operations

Как управлять зависимостями?

Создаю простой конфиг и устанавливаю :

Изначально, я явно указывал зависимости, но практика интеграции со сторонними сервисами показала, что лучшим способом будет все-таки хранение зависимостей в файле.

Возникает очень тонкий момент. Фиксировать актуальную на момент разработки версию или всегда ставить последнюю?

Поэтому для себя выработал правило:

  1. Всегда фиксировать версию для конечных продуктов, так как какие версии использовать — это их ответственность.
  2. Не фиксировать используемую версию для устанавливаемых пакетов. Или ограничивать диапазоном, если того требует функционал пакета.

tee(iterable, n=2)

Инструмент tee создает n количество итераторов из одной итерируемой. Это значит, что вы можете создать несколько итераторов из одной итерируемой. Давайте взглянем на следующий код, чтобы понять, что к чему:

Python

from itertools import tee

data = ‘ABCDE’ iter1, iter2 = tee(data)

for item in iter1: print(item)

1 2 3 4 5 6 7

fromitertoolsimporttee

data=’ABCDE’

iter1,iter2=tee(data)

foritem initer1

print(item)

Результат:

Python

A B C D E

1 2 3 4 5

A B C D E

Python

for item in iter2: print(item)

1 2

foritem initer2

print(item)

Результат:

Python

A B C D E

1 2 3 4 5

A B C D E

Здесь мы создаем строку из 5 букв и передаем её tee. Так как tee по умолчанию равен 2, мы используем множественное присваивание для получения двух итераторов, которые вернет tee. Далее, мы зацикливаем каждый итератор и выводим их содержимое. Как мы видим, их содержимое одинаково.

4) Mathematical style:

List comprehensions became the preferred style for list manipulation in Python since introduced in version 2.0 by PEP 202. The rationale behind it is that List comprehensions provide a more concise way to create lists in situations where and and/or nested loops would currently be used.

Generator expressions were introduced in version 2.4 by PEP 289. A generator expression is better for situations where you don’t really need (or want) to have a full list created in memory — like when you just want to iterate over the elements one at a time. If you are only iterating over the list, you can think of a generator expression as a lazy evaluated list comprehension:

  • See this Python history blog post by GvR.
  • This syntax is inspired by the set-builder notation in math.
  • Python 3 has also and dict comprehensions.

Цикл while


Цикл while также используется для повторения частей кода, но вместо зацикливания на n количество раз, он выполняет работу до тех пор, пока не достигнет определенного условия. Давайте взглянем на простой пример:

Python

i = 0 while i < 10: print(i) i = i + 1

1 2 3 4

i=

whilei<10

print(i)

i=i+1

Цикл while является своего рода условным оператором. Вот что значит этот код: пока переменная i меньше единицы, её нужно выводить на экран. Далее, в конце, мы увеличиваем её значение на единицу. Если вы запустите этот код, он выдаст от 0 до 9, каждая цифра будет в отдельной строке, после чего задача будет выполнена. Если вы удалите ту часть, в которой мы увеличиваем значение i, то мы получим бесконечный цикл. Как правило – это плохо. Бесконечные циклы известны как логические ошибки, и их нужно избегать. Существует другой способ вырваться из цикла, для этого нужно использовать встроенную функцию break. Давайте посмотрим, как это работает:

Python

while i < 10: print(i) if i == 5: break i += 1

1 2 3 4 5 6 7

whilei<10

print(i)

ifi==5

break

i+=1

В этой части кода мы добавили условное выражение для проверки того, равняется ли когда-либо переменная i цифре 5. Если нет, тогда мы разрываем цикл. Как вы видите в выдаче кода, как только значение достигает пяти, код останавливается, даже если мы ранее указали while продолжать цикл, пока переменная не достигнет значения 10

Обратите внимание на то, что мы изменили то, как мы увеличиваем значение при помощи +=. Это удобный ярлык, который вы можете также использовать в других операциях, таких как вычитание -= и умножение *=

Встроенный break также известен как инструмент управления потока. Существует еще один, под названием continue, который в основном используется для пропуска итерации, или перейти к следующей итерации. Вот один из способов его применения:

Python

i = 0

while i < 10: if i == 3: i += 1 continue print(i) if i == 5: break i += 1

1 2 3 4 5 6 7 8 9 10 11 12

i=

whilei<10

ifi==3

i+=1

continue

print(i)

ifi==5

break

i+=1

Слегка запутанно, не так ли? Мы добавили второе условное выражение, которое проверяет, не равняется ли i трем. Если да, мы увеличиваем переменную и переходим к следующему циклу, который удачно пропускает вывод значения 3 на экран. Как и ранее, когда мы достигаем значения 5, мы разрываем цикл. Существует еще одна тема, касающаяся циклов, которую нам нужно затронуть – это оператор else.

And now for something completely different

rong>Michael Palin: Hello, good evening and welcome to another edition of Blood, Devastation, Death War and Horror, and later on we’ll be meeting a man who does gardening. But first on the show we’ve got a man who speaks entirely in anagrams. Palin: I believe you’re working on an anagram version of Shakespeare? Eric Idle: Sey, sey — taht si crreoct, er — ta the mnemot I’m wroking on ‘The Mating of the Wersh’. Palin: Have you done ‘Hamlet’? Idle: ‘Thamle’. ‘Be ot or bot ne ot, tath is the nestquoi.’ Palin: And what is your next project? Idle: ‘Ring Kichard the Thrid’. Palin: I’m sorry? Idle: ‘A shroe! A shroe! My dingkom for a shroe!’ Palin: Ah, Ring Kichard, yes… but surely that’s not an anagram, that’s a spoonerism. Idle: (offended) If you’re going to split hairs, I’m going to piss off.

Version Operating System Description MD5 Sum File Size GPG
Gzipped source tarball Source release 387e63fe42c40a29e3408ce231315516 24151047 SIG
XZ compressed source tarball Source release e16df33cd7b58702e57e137f8f5d13e7 18020412 SIG
macOS 64-bit installer Mac OS X for OS X 10.9 and later 8464bc5341d3444b2ccad001d88b752b 30231094 SIG
Windows help file Windows bf7942cdd74f34aa4f485730a714cc47 8529593 SIG
Windows x86-64 embeddable zip file Windows for AMD64/EM64T/x64 c68f60422a0e43dabf54b84a0e92ed6a 8170006 SIG
Windows x86-64 executable installer Windows for AMD64/EM64T/x64 12297fb08088d1002f7e93a93fd779c6 27866224 SIG
Windows x86-64 web-based installer Windows for AMD64/EM64T/x64 7c382afb4d8faa0a82973e44caf02949 1364112 SIG
Windows x86 embeddable zip file Windows 910c307f58282aaa88a2e9df38083ed2 7305457 SIG
Windows x86 executable installer Windows c3d71a80f518cfba4d038de53bca2734 26781976 SIG
Windows x86 web-based installer Windows 075a93add0ac3d070b113f71442ace37 1328184 SIG

Remove an element from List by value using list.remove()

Python’s list provides a member function to remove an element from list i.e.

list.remove(value)

For example,

Suppose we have a list of numbers i.e.

# List of numbers
listOfnum = 
# Remove first occurrence of 56 from List 
listOfnum.remove(56)

Check if element exists in list i.e.

# Check if element exist in List, before removing
if 99 in listOfnum:
    listOfnum.remove(99)
else:
    print("Given Element Not Found in List")
# If given element doesn't exists in list, then remove() can throw Error
# Therefore use try / except while calling list.remove()
try :
    listOfnum.remove(99)
except ValueError:
    print("Given Element Not Found in List")

С этим читают