Pergunta

métodos de dicionários dict.keys (), dict.items () e dict.values ??() retorno “vistas” em vez de listas. http://docs.python.org/dev/3.0/whatsnew//3.0 .html

Em primeiro lugar, como é uma visão diferente de um iterador? Em segundo lugar, qual é o benefício dessa mudança? É apenas por motivos de desempenho?

Não parece intuitivo para mim, ou seja, eu estou pedindo uma lista de coisa (dá-me todas as suas chaves) e eu estou ficando mais alguma coisa para trás. Será que este confundir as pessoas?

Foi útil?

Solução

Você está efetivamente recebendo uma lista. Não é apenas uma cópia da lista interna, mas algo que age como se onde uma lista, mas representa apenas o estado interno.

Essa é a mesma forma como ele é implementado em Java (e provavelmente muitas outras linguagens / ambientes bem).

A principal razão é que, para muitos casos de uso de retornar uma lista completamente separada é desnecessário e um desperdício. Seria necessário copiar todo o conteúdo (que pode ou muitos não ser muito).

Se você simplesmente quer iterar sobre as chaves, em seguida, criar uma nova lista não é necessário. E se você de fato precisa dele como uma lista separada (como uma cópia), então você pode facilmente criar essa lista a partir da visão.

Outras dicas

A resposta de Joachim Sauer explica muito bem por um list não é devolvido. Mas isso deixa a pergunta por que essas funções não voltaria iterators, assim como iteritems etc. fez em Python 2.

Um iterador é muito mais restritiva do que um recipiente. Por exemplo, um iterador não permite mais do que uma passagem; se você tentar uma segunda passagem, você vai descobrir que é vazio. Portanto, operações como elem in cont são suportados por contentores, mas não pode ser suportado pelo iterators: uma vez que você verificar se um elemento é "in" o iterador, o iterador é destruído

Por outro lado, a obtenção de um recipiente normalmente requer a realização de uma cópia como a criação de uma lista de chaves do dicionário.

O objeto view tem o melhor dos dois mundos: ele se comporta como um recipiente, e ainda não faz uma cópia do dicionário! É, na verdade, uma espécie de um recipiente somente leitura virtual que funciona ligando ao dicionário subjacente. Eu não sei se ele é visto em qualquer outro lugar no Python padrão.

Editar:

@AntonyHatchkins: a razão pela qual não retorna uma função de gerador é que ele não permitiria uma operação in rápido. Sim, in funciona para as funções de gerador (quando você chamá-los). Ou seja, você pode fazer isso:

def f():
  for i in range(10):
    yield i

5 in f() # True

Mas de acordo com a definição de in, se o lado direito é um gerador, python irá percorrer todos os itens n do gerador - que conduzem a complexidade de tempo O(n). Não há nada que você possa fazer sobre isso, porque isso é o comportamento só faz sentido um gerador arbitrário.

Por outro lado, no caso do ponto de vista dicionário, você pode implementar in qualquer jeito que você gosta, porque você sabe mais sobre os dados que você gerencia. E, de fato in é implementado com a complexidade O(1) usando uma tabela hash. Você pode verificá-la executando

>>> d = dict(zip(range(50000000), range(50000000)))
>>> 49999999 in d
True
>>> 49999999 in iter(d) # kinda how generator function would work
True
>>>

e percebendo o quão rápido o primeiro in é comparado com o segundo in.

Como já foi mencionado na pergunta relacionada, visão tem método len(), que o iterador não tem (ainda lista tem).

Outro benefício de retornar uma vista em vez de uma lista é que, pelo menos, para as chaves que ele tem um teste de adesão optimizada em O (1) as operações em vez de O (N) para a lista (ou iteração).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top