Как заставить Python различать равные целые числа - PullRequest
1 голос
/ 16 декабря 2011

Возникла небольшая проблема, различающая одинаковые целые числа.

В следующем (что, очевидно, тривиальный случай) a, b, c являются целыми числами.Я хочу создать дисионар, дикцию, которая будет содержать {a: 'foo', b: 'bar', c: 'baz'}

diction = {} 
for i in (a, b, c):
    j = ('foo', 'bar', 'baz')[(a, b, c).index(i)]
    diction[i] = j

Все работает очень хорошо, например, дои b одинаковы: третья строка даст индекс 0 как для a, так и для b, в результате j = 'foo' для каждого случая.

Я знаю, списки могут быть скопированы с помощью

list_a = [1, 2, 3]
list_b = list(list_a)

или

list_b = list_a[:]

Итак, есть ли способ сделать это с моими одинаковыми целыми числами?

(Я попытался сделать один с плавающей точкой, но значение остается тем же, так чтоне работает.)

Ответы [ 5 ]

3 голосов
/ 16 декабря 2011

Чтобы создать словарь из двух разных итераций, вы можете использовать следующий код:

d = dict(zip((a, b, c), ('foo', 'bar', 'baz')))

, где zip используется для объединения обоих итераций в список кортежей, которые можно передать в словарьКонструктор.

Обратите внимание, что если a==b, то 'foo' будет перезаписано 'bar', так как значения добавляются в словарь в том же порядке, в котором они итерируются, как если бы вы использовалиэтот код:

d[a] = 'foo'
d[b] = 'bar'
d[c] = 'baz'

Это просто стандартное поведение словаря, когда новое значение присваивается уже известной клавише, значение перезаписывается.

Если вы предпочитаетечтобы сохранить все значения в списке, вы можете использовать collections.defaultdict следующим образом:

from collections import defaultdict

d = defaultdict(list)
for key, value in zip((a, b, c), ('foo', 'bar', 'baz')):
    d[key].append(value)
2 голосов
/ 16 декабря 2011

Вы не можете различить идентичные объекты.

1 голос
/ 16 декабря 2011

Вы можете различить их, если они не попадают между -5 и 256

См. Также Оператор "is" ведет себя неожиданно с целыми числами

http://docs.python.org/c-api/int.html

Текущая реализация хранит массив целочисленных объектов для всех целых чисел от -5 до 256, когда вы создаете int в этом диапазоне, вы фактически просто возвращаете ссылку на существующий объект.Так что должно быть возможно изменить значение 1. Я подозреваю, что поведение Python в этом случае не определено.: -)

In [30]: a = 257

In [31]: a is 257
Out[31]: False

In [32]: a = 256

In [33]: a is 256
Out[33]: True

Возможно, вам придется свернуть свой собственный словарь как объект, который реализует такого рода поведение, хотя ... и он все равно не сможет ничего делать между -5 и256. Мне нужно было бы больше копать, чтобы быть уверенным.

1 голос
/ 16 декабря 2011

Если a и b имеют одно и то же значение, вы не можете ожидать, что они будут указывать на разные позиции в словаре, если используются в качестве ключей.Значения ключей в словарях должны быть уникальными.

Также, если у вас есть две последовательности, самый простой способ сделать из них словарь - это сжать их вместе:

tup = (a,b,c)
val = ('foo', 'bar', 'baz')
diction = dict(zip(tup, val))
0 голосов
/ 16 декабря 2011

Все ответы пока верны - идентичные ключи не могут быть повторно использованы в словаре. Если вы абсолютно должны попытаться сделать что-то подобное, но не можете гарантировать, что a, b и c имеют разные значения, вы могли бы попробовать что-то вроде этого:

d = dict(zip((id(k) for k in (a,b,c)), ('foo', 'bar', 'baz')))

Когда вы будете искать свои значения, вы должны помнить, чтобы сделать это так:

d[id(a)]

Это может помочь, но я не уверен, что вы на самом деле здесь.

...