Пояснения к спискам обеспечивают краткий способ создания списков. Обычные приложения - создавать новые списки, в которых каждый элемент является результатом некоторых операций, применяемых к каждому члену другой последовательности или итерируемым, или для создания подпоследовательности тех элементов, которые удовлетворяют определенному условию.
blockquote>О вашем вопросе, понимание списка делает то же самое, что и следующий «простой» код Python:
>>> l = [] >>> for x in range(10): ... l.append(x**2) >>> l [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Как вы пишете его в одной строке? Хм ... мы можем ... возможно ... использовать
map()
сlambda
:>>> list(map(lambda x: x**2, range(10))) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Но это не проще и проще просто использовать понимание списка?
>>> [x**2 for x in range(10)] [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
В принципе, мы можем делать все с помощью
x
. Не толькоx**2
. Например, запустите методx
:>>> [x.strip() for x in ('foo\n', 'bar\n', 'baz\n')] ['foo', 'bar', 'baz']
Или используйте
x
в качестве аргумента другой функции:>>> [int(x) for x in ('1', '2', '3')] [1, 2, 3]
Мы также можем использовать
x
в качестве ключа объектаdict
. Давайте посмотрим:>>> d = {'foo': '10', 'bar': '20', 'baz': '30'} >>> [d[x] for x in ['foo', 'baz']] ['10', '30']
Как насчет комбинации?
>>> d = {'foo': '10', 'bar': '20', 'baz': '30'} >>> [int(d[x].rstrip('0')) for x in ['foo', 'baz']] [1, 3]
И так далее.
Вы также можете использовать
if
илиif...else
в понимании списка. Например, вам нужны только нечетные числа вrange(10)
. Вы можете сделать:>>> l = [] >>> for x in range(10): ... if x%2: ... l.append(x) >>> l [1, 3, 5, 7, 9]
Ах, это слишком сложно. Что касается следующей версии?
>>> [x for x in range(10) if x%2] [1, 3, 5, 7, 9]
Чтобы использовать тернарное выражение
if...else
, вам нужно поместитьif ... else ...
послеx
, а не послеrange(10)
:>>> [i if i%2 != 0 else None for i in range(10)] [None, 1, None, 3, None, 5, None, 7, None, 9]
Вы слышали о понимании вложенного списка ? Вы можете поместить два или более
for
s в одно понимание списка . Например:>>> [i for x in [[1, 2, 3], [4, 5, 6]] for i in x] [1, 2, 3, 4, 5, 6] >>> [j for x in [[[1, 2], [3]], [[4, 5], [6]]] for i in x for j in i] [1, 2, 3, 4, 5, 6]
Давайте поговорим о первой части,
for x in [[1, 2, 3], [4, 5, 6]]
, которая дает[1, 2, 3]
и[4, 5, 6]
. Затемfor i in x
дает1
,2
,3
и4
,5
,6
.Предупреждение: вам всегда нужно поставить
for x in [[1, 2, 3], [4, 5, 6]]
доfor i in x
:>>> [j for j in x for x in [[1, 2, 3], [4, 5, 6]]] Traceback (most recent call last): File "", line 1, in
NameError: name 'x' is not defined У нас также есть набор понятий , dict и генераторные выражения .
Установленные опознавания и понимание списка в основном одинаковы, но первый возвращает набор вместо a list :
>>> {x for x in [1, 1, 2, 3, 3, 1]} {1, 2, 3}
Это то же самое, что:
>>> set([i for i in [1, 1, 2, 3, 3, 1]]) {1, 2, 3}
Понимание dict выглядит определение набора, но вместо
{i for i in ...}
оно использует{key: value for key, value in ...}
или{i: i for i in ...}
.Например:
>>> {i: i**2 for i in range(5)} {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
И это равно:
>>> d = {} >>> for i in range(5): ... d[i] = i**2 >>> d {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
Предоставляет ли
(i for i in range(5))
кортеж ? Нет !, это выражение генератора . Который возвращает генератор:>>> (i for i in range(5))
at 0x7f52703fbca8> Это то же самое, что:
>>> def gen(): ... for i in range(5): ... yield i >>> gen()
И вы можете использовать его как генератор:
>>> gen = (i for i in range(5)) >>> next(gen) 0 >>> next(gen) 1 >>> list(gen) [2, 3, 4] >>> next(gen) Traceback (most recent call last): File "", line 1, in
StopIteration Примечание : Если вы используете понимание списка внутри функции , вам не понадобится
[]
, если эта функция может зацикливаться на генераторе. Например,sum()
:>>> sum(i**2 for i in range(5)) 30
Связанный (об генераторах): Понимание генераторов в Python .
Сначала переведите лондонское время в объект POSIXct
:
pb.txt <- "2009-06-03 19:30"
pb.date <- as.POSIXct(pb.txt, tz="Europe/London")
Затем используйте format
для печати даты в другом часовом поясе:
> format(pb.date, tz="America/Los_Angeles",usetz=TRUE)
[1] "2009-06-03 11:30:00 PDT"
Есть несколько способов найти правильный идентификатор часового пояса для использования. Подробнее в этом сообщении в блоге Revolutions: Преобразование часовых поясов в R: советы, трюки и ловушки
Измените атрибут tzone объекта «POSIXct»:
> pb.txt <- "2009-06-03 19:30"
> pb.date <- as.POSIXct(pb.txt, tz="Europe/London")
> attributes(pb.date)$tzone <- "America/Los_Angeles"
> pb.date
[1] "2009-06-03 11:30:00 PDT"
Обратите внимание, что это все еще объект POSIXct, tzone изменился, и было применено правильное смещение:
> attributes(pb.date)
$class
[1] "POSIXct" "POSIXt"
$tzone
[1] "America/Los_Angeles"
Если вы хотите сделать это в одной строке, напомните, что любой объект POSIXct
в R - это просто число (секунды UTC с начала эпохи) и что «часовой пояс» - это просто атрибут, который определяет, как это число напечатано .
Поэтому мы можем использовать structure
следующим образом:
x = as.POSIXct("2009-06-03 19:30", tz = "Europe/London")
structure(as.integer(x), class = class(x), tzone = 'America/Los_Angeles')
# [1] "2009-06-03 11:30:00 PDT"
as.integer
разделяет класс и атрибуты x
и structure
позволяет нам перестроить / настроить их. class(x)
является сокращением для c('POSIXct', 'POSIXt')
; если ваш объект имеет миллисекунды, и вы хотите отслеживать их, вы можете использовать as.numeric(x)
.
Пакет lubridate
содержит две функции для преобразования часовых поясов. Согласно страницам справки:
force_tz
возвращает дату-время с тем же самым часовым временем, что и x
в новом часовом поясе.
force_tz(time, tzone = "America/Los_Angeles")
with_tz
изменяет часовой пояс, в котором отображается момент. Время, отображаемое для мгновенных изменений, но момент времени, описанный, остается неизменным.
with_tz(time, tzone = "America/Los_Angeles")