Python для сбора данных

Алла Тамбовцева, НИУ ВШЭ

Практикум 1: решения

Задача 1

In [1]:
girls = ["Иветта", "Виолетта", "Кассандра", "Вирджиния", 
         "Амелия", "Розамунда", "Янина", "Беатриса"]
In [2]:
print(girls[1:5]) # 1
print(girls[3:]) # 2
print(girls[0:2] + girls[3:5]) # 3
print(girls[2:3] + girls[4:6]) # 4
['Виолетта', 'Кассандра', 'Вирджиния', 'Амелия']
['Вирджиния', 'Амелия', 'Розамунда', 'Янина', 'Беатриса']
['Иветта', 'Виолетта', 'Вирджиния', 'Амелия']
['Кассандра', 'Амелия', 'Розамунда']

Насчет последнего списка: его можно получить и иначе, но нужно иметь в виду, что выбор одного объекта без среза вернет не список, а отдельную строку, которую нельзя склеить со списком через +:

In [3]:
girls[2]
Out[3]:
'Кассандра'
In [4]:
girls[2] + girls[4:6]
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-a1f4eb3072bf> in <module>()
----> 1 girls[2] + girls[4:6]

TypeError: must be str, not list

В таком случае потребуются дополнительные квадратные скобки (правда это уже будет не так изящно):

In [5]:
[girls[2]] + girls[4:6]
Out[5]:
['Кассандра', 'Амелия', 'Розамунда']

Обратите внимание: срезы вида L[k:k] всегда пустые!

In [6]:
girls[2:2] # срез от 2-ого элемента по 2-ой элемент, не включая 2-ой
Out[6]:
[]

Задача 2

In [7]:
numbers = [1, 5, 6, 8, 10, 21, 25, 1, 0, -9, 9]
In [8]:
k = int(input("Введите целое число от 1 до 10: "))
print(numbers[k - 1])
Введите целое число от 1 до 10: 3
6

Задача 3

In [9]:
L = [1,2,3,4]

for i in range(len(L)):
    a = L[i] + L[i-1]
    print(a)
5
3
5
7

Разберем код на части. Что такое range(len(L))?

In [10]:
list(range(len(L))) # индексы элементов списка L
Out[10]:
[0, 1, 2, 3]

Значит цикл for бегает по индексам списка L. Тогда L[i] – это i-тый элемент списка L, а L[i-1] – элемент, предшествующий i-тому элементу. Эти два элемента складываются, и результат сохраняется в a.

Посмотрим. Если i = 0, то получаем L[0] и L[-1]. Значит, на первом шаге (на первой итерации) цикла мы складываем первый и последний элементы списка.

1 + 4 = 5

Двигаемся дальше. Если i = 1, то получаем L[1] и L[0]. Значит, на втором шаге цикла мы складываем второй и первый элементы списка.

2 + 1 = 3

И так далее.

Почему этот код интересен? Потому, что он не ломается: Python не возражает против отрицательных индексов элементов, он просто начинает считать элементы с конца списка.

Задача 4

In [11]:
income = [25000, 32000, 120000, 5000]
In [16]:
import math
log_income = []
for i in income:
    log_income.append(math.log(i))
print(log_income)
[10.126631103850338, 10.373491181781864, 11.695247021764184, 8.517193191416238]

Давайте заодно посмотрим на альтернативу циклам при создании списков – на списковые включения (list comprehensions). Они позволяют создавать новые списки на основе старых более компактным и быстрым образом, без явных циклов. Чтобы понять, как они работают, нужно прочитать код с циклом снизу вверх: сначала что делаем, а потом – с чем.

In [13]:
log_income = [math.log(i) for i in income] 
log_income
Out[13]:
[10.126631103850338, 10.373491181781864, 11.695247021764184, 8.517193191416238]

Теперь таким же образом получим список из натуральных логарифмов:

Задача 5

In [14]:
words = ["Speak ","to", "me ", "of", "Florence" ,"And ", "of", "the", "Renaissance"]

Для закрепления воспользуемся списковыми включениями еще раз. Если учесть, что методы на одних и тех же объектах можно «наслаивать» друг на друга, получим очень лаконичное решение в одну строчку:

In [15]:
words_clean = [w.lower().strip() for w in words]
words_clean
Out[15]:
['speak', 'to', 'me', 'of', 'florence', 'and', 'of', 'the', 'renaissance']