Por que a lista não possui um método "get" seguro como o dicionário?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
Por que a lista não possui um método "get" seguro como o dicionário?
>>> d = {'a':'b'}
>>> d['a']
'b'
>>> d['c']
KeyError: 'c'
>>> d.get('c', 'fail')
'fail'
>>> l = [1]
>>> l[10]
IndexError: list index out of range
l[10:11]
vez del[10]
, por exemplo. () Th sublista terá o elemento desejado, se existir).get
. Seria o equivalente al[i] if i < len(l) else default
, mas mais legível, mais concisa, e permitindoi
a ser uma expressão sem ter que recalcular-loNone
se não existisse. Teria sido bom dizerx = expensive().get(0, None)
para não ter que colocar o retorno inútil do caro em uma variável temporária.Respostas:
Por fim, provavelmente não possui um
.get
método seguro , porque adict
é uma coleção associativa (os valores estão associados aos nomes), onde é ineficiente verificar se uma chave está presente (e retornar seu valor) sem gerar uma exceção, embora seja super trivial para evitar exceções ao acessar os elementos da lista (como olen
método é muito rápido). O.get
método permite que você consulte o valor associado a um nome, não acesse diretamente o 37º item no dicionário (que seria mais parecido com o que você está pedindo na sua lista).Obviamente, você pode implementar isso sozinho:
Você pode até monkeipá-lo no
__builtins__.list
construtor__main__
, mas isso seria uma mudança menos difundida, já que a maioria dos códigos não o usa. Se você quiser apenas usá-lo com listas criadas por seu próprio código, basta subclassificarlist
e adicionar oget
método.fonte
list
.get
resolve um problema que as listas não têm - uma maneira eficiente de evitar exceções ao obter dados que podem não existir. É super trivial e muito eficiente saber o que é um índice de lista válido, mas não há uma maneira particularmente boa de fazer isso para valores-chave em um dicionário.O(1)
. Não será tão rápido em termos brutos quanto a verificaçãolen
, mas do ponto de vista da complexidade, são todosO(1)
. A resposta certa é o uso típico / semântica um ...dict
é apenas o melhor caso O (1), nem todos os casos..get()
ou tem problemas em outras partes do seu código (ou ambiente). O objetivo de usar esse método é a legibilidade do código. A técnica "vanilla" requer quatro linhas de código em todos os lugares em que isso precisa ser feito. A.get()
técnica requer apenas um e pode ser facilmente encadeada com chamadas de método subsequentes (por exemplomy_list.get(2, '').uppercase()
).Isso funciona se você quiser o primeiro elemento, como
my_list.get(0)
Eu sei que não é exatamente o que você pediu, mas pode ajudar os outros.
fonte
next(iter(my_list[index:index+1]), 'fail')
Permite a qualquer índice, não apenas 0. Ou menos FP, mas sem dúvida mais Pythonic, e quase certamente mais legível:my_list[index] if index < len(my_list) else 'fail'
.Provavelmente porque simplesmente não fazia muito sentido para a semântica da lista. No entanto, você pode facilmente criar seus próprios subclasses.
fonte
get
método. Legibilidade conta. E a legibilidade sofre com cada classe adicional desnecessária. Basta usar atry / except
abordagem sem criar subclasses.Em vez de usar .get, usar desta forma deve estar ok para listas. Apenas uma diferença de uso.
fonte
.get
método (exceto que não tenho certeza de como explicaria o que o índice significava nesse caso, ou por que um dia iria falhar).lst[i] if -len(lst) <= i < len(l) else 'fail'
Tente o seguinte:
fonte
Créditos a jose.angel.jimenez
Para os fãs "oneliner" ...
Se você deseja o primeiro elemento de uma lista ou se deseja um valor padrão, se a lista estiver vazia, tente:
retorna
a
e
retorna
default
Exemplos para outros elementos…
Com fallback padrão…
Testado com
Python 3.6.0 (v3.6.0:41df79263a11, Dec 22 2016, 17:23:13)
fonte
value, = liste[:1] or ('default',)
. Parece que você precisa dos parênteses.A melhor coisa que você pode fazer é converter a lista em um dict e acessá-la com o método get:
fonte
zip range len
coisa, pode-se usar apenasdict(enumerate(my_list))
Então, eu fiz mais algumas pesquisas sobre isso e verifica-se que não há nada específico para isso. Fiquei empolgado quando encontrei list.index (value), ele retorna o índice de um item especificado, mas não há nada para obter o valor em um índice específico. Portanto, se você não quiser usar a solução safe_list_get, que eu acho muito boa. Aqui estão algumas instruções liner if que podem fazer o trabalho para você, dependendo do cenário:
Você também pode usar Nenhum em vez de 'Não', o que faz mais sentido:
Além disso, se você deseja apenas obter o primeiro ou o último item da lista, isso funciona
Você também pode transformá-las em funções, mas eu ainda gostei da solução de exceção IndexError. Eu experimentei uma versão dummied da
safe_list_get
solução e a tornei um pouco mais simples (sem padrão):Não foram comparados para ver o que é mais rápido.
fonte
list
ao subclassificá-lo. Dessa forma, o construtor pode usar umalist
ou qualquer coisa que se comporte como uma lista, e a nova instância se comporta como umalist
. Veja a resposta de Keith abaixo, que deve ser o IMHO aceito.dict.get()
retornar um valor padrão de uma referência de índice de lista em vez de ter que pegarIndexError
? Então, realmente é sobre o recurso de idioma / biblioteca (e não OOP x contexto FP) Além disso, provavelmente é necessário qualificar o uso de 'pythonic' como talvez WWGD (como é conhecido o seu desprezo pelo FP Python) e não necessariamente apenas satisfazendo o PEP8 / 20.el = x[4] if len(x) == 4 else 'No'
- você quer dizerlen(x) > 4
?x[4]
está fora dos limites selen(x) == 4
.Os dicionários são para pesquisas. Faz sentido perguntar se uma entrada existe ou não. As listas geralmente são iteradas. Não é comum perguntar se L [10] existe, mas se o comprimento de L é 11.
fonte
O seu caso de uso é basicamente relevante apenas para a criação de matrizes e matrizes de comprimento fixo, para que você saiba quanto tempo demora antes. Nesse caso, você normalmente também os cria antes de preenchê-los com Nenhum ou 0, para que, de fato, já exista qualquer índice que você usar.
Você poderia dizer o seguinte: preciso de .get () nos dicionários com bastante frequência. Depois de dez anos como programador em tempo integral, acho que nunca precisei disso em uma lista. :)
fonte
'lalala' in url.split('/')[2:]
. Mas o problema com sua solução aqui é que você olha apenas para o segundo elemento. E se o URL for '/ monkeybonkey / lalala'? Você receberá um,True
mesmo que o URL seja inválido.