Как избежать специального случая, когда список имеет длину 1? [Дубликат]

Я был удивлен, что никто еще не рекомендовал использовать встроенную функцию filter .

    import operator
    import string # only for the example you could use a custom string

    s = "1212edjaq"

Предположим, что мы хотим отфильтровать все, что не является числом. Использование метода встроенного фильтра «... эквивалентно выражению генератора (элемент для элемента в iterable if function (item))» [ Python 3 Builtins: Filter ]

    sList = list(s)
    intsList = list(string.digits)
    obj = filter(lambda x: operator.contains(intsList, x), sList)))

В Python 3 это возвращает

    >>  

. Чтобы получить печатную строку,

    nums = "".join(list(obj))
    print(nums)
    >> "1212"

Я не знаю, как фильтр занимает место в терминах эффективность, но хорошо знать, как использовать при составлении списков и т. д.

UPDATE

Логически, поскольку работы фильтра вы также можете использовать понимание списка и из того, что у меня есть прочитайте, что он должен быть более эффективным, потому что лямбды - это руководители хедж-фондов на уличной улице в мире функций программирования. Другим плюсом является то, что это однострочный, который не требует импорта. Например, используя ту же строку 's', определенную выше,

      num = "".join([i for i in s if i.isdigit()])

Вот и все. Возврат будет строкой всех символов, которые являются цифрами в исходной строке.

Если у вас есть определенный список допустимых / неприемлемых символов, вам нужно только отредактировать часть «если» в понимании списка.

      target_chars = "".join([i for i in s if i in some_list]) 

или, альтернативно,

      target_chars = "".join([i for i in s if i not in some_list])

13
задан user1723765 21 December 2012 в 14:22
поделиться

2 ответа

Это документированная функция:

Если x имеет длину 1, это numeric (в смысле is.numeric) и x >= 1, выборка по образцу происходит из 1:x. Обратите внимание, что эта удобная функция может привести к нежелательному поведению, когда x имеет разную длину в таких вызовах, как sample(x).

Альтернативой является написать свою собственную функцию, чтобы избежать этой функции:

sample.vec <- function(x, ...) x[sample(length(x), ...)]
sample.vec(10)
# [1] 10
sample.vec(10, 3, replace = TRUE)
# [1] 10 10 10

Некоторые функции с аналогичным поведением перечислены в seq vs seq_along. Когда использование seq приведет к непреднамеренным результатам?

16
ответ дан Community 23 August 2018 в 23:48
поделиться

При подаче только одного номера sample работает как sample.int (см. ?sample). Если вы хотите убедиться, что это только образцы из вектора, который вы ему даете, вы можете работать с индексами и использовать эту конструкцию:

x[sample(length(x))]

Это дает правильный результат независимо от длины x, и без необходимости добавлять условие if, проверяющее длину.

Пример:

mylist <- list(
  a = 5,
  b = c(2,4),
  d = integer(0)
)

mysample <- lapply(mylist,function(x) x[sample(length(x))])

> mysample
$a
[1] 5

$b
[1] 2 4

$d
integer(0)

Примечание: вы можете заменить sample на sample.int, чтобы получить небольшое усиление скорости.

15
ответ дан Will 23 August 2018 в 23:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: