Поведение словаря Weird Python [duplicate]

Я думаю, что лучшим решением этой проблемы является использование maven-install-plugin для автоматической установки файлов во время установки. Вот как я настроил его для своего проекта.

Сначала добавьте путь (где вы храните локальные .jars) как свойство.


    /path/to/jar

Затем в разделе plugins добавьте плагин для установки банок при компиляции .


    org.apache.maven.plugins
    maven-install-plugin
    2.5.2
    
        
            1
            initialize
            
                install-file
            
            
                com.local.jar 
                appengine-api
                1.0
                jar
                ${local.sdk}/lib/impl/appengine-api.jar
            
        
        
            appengine-api-stubs
            initialize
            
                install-file
            
            
                com.local.jar
                appengine-api-stubs
                1.0
                jar
                ${local.sdk}/lib/impl/appengine-api-stubs.jar
            
        
    

Наконец, в зависимостях вы можете добавить jars


    com.local.jar
    appengine-api
    1.0



    com.local.jar
    appengine-api-stubs
    1.0
    test

. Создав свой проект таким образом, проект будет продолжать строить, даже когда вы его берете на другой компьютер (учитывая, что он имеет все файлы jar в пути, указанном свойством local.sdk).

Для groupId используйте уникальное имя, чтобы убедиться, что конфликтов нет.

Теперь, когда ваши mvn install или mvn test локальные банки будут добавлены автоматически.

63
задан Bach 19 June 2014 в 08:24
поделиться

6 ответов

Он явно упоминается на странице документа Python (для Python 2.7 ), что

Использование iteritems() при добавлении или удалении записей в словаре может вызвать RuntimeError или не выполнить итерацию по всем элементам.

Аналогично для Python 3 .

То же самое верно для iter(d), d.iterkeys() и d.itervalues(), и я скажу, что он делает это для for k, v in d.items(): (я не могу точно запомнить, что делает for, но я не удивлюсь, если реализация, названная iter(d)), .

42
ответ дан Craig McQueen 24 August 2018 в 10:26
поделиться

У меня есть большой словарь, содержащий массивы Numpy, поэтому свойство dict.copy (). keys (), предложенное @ murgatroid99, было невозможно (хотя оно сработало). Вместо этого я просто преобразовал key_view в список, и он отлично работал (в Python 3.4):

for item in list(dict_d.keys()):
    temp = dict_d.pop(item)
    dict_d['some_key'] = 1  # Some value

Я понимаю, что это не погружается в философскую сферу внутренней работы Python, как ответы выше, но он обеспечивает практическое решение указанной проблемы.

2
ответ дан 2cynykyl 24 August 2018 в 10:26
поделиться

У меня такая же проблема, и я использовал следующую процедуру для решения этой проблемы.

Список Python может быть итерационным, даже если вы изменяете его во время итерации по нему. поэтому для следующего кода он будет печатать бесконечно.

for i in list:
   list.append(1)
   print 1

Таким образом, используя список и dict совместно, вы можете решить эту проблему.

d_list=[]
 d_dict = {} 
 for k in d_list:
    if d_dict[k] is not -1:
       d_dict[f(k)] = -1 # rather than deleting it mark it with -1 or other value to specify that it will be not considered further(deleted)
       d_dict[g(k)] = v # add a new item 
       d_list.append(g(k))
1
ответ дан brasofilo 24 August 2018 в 10:26
поделиться

Следующий код показывает, что это неверно определено:

def f(x):
    return x

def g(x):
    return x+1

def h(x):
    return x+10

try:
    d = {1:"a", 2:"b", 3:"c"}
    for k, v in d.iteritems():
        del d[f(k)]
        d[g(k)] = v+"x"
    print d
except Exception as e:
    print "Exception:", e

try:
    d = {1:"a", 2:"b", 3:"c"}
    for k, v in d.iteritems():
        del d[f(k)]
        d[h(k)] = v+"x"
    print d
except Exception as e:
    print "Exception:", e

Первый пример вызывает g (k) и выдает исключение (измененный размер словаря во время итерации).

Второй пример вызывает h (k) и не вызывает исключение, но выводит:

{21: 'axx', 22: 'bxx', 23: 'cxx'}

Что, глядя на код, кажется неправильным - я бы ожидал чего-то вроде:

{11: 'ax', 12: 'bx', 13: 'cx'}
6
ответ дан combatdave 24 August 2018 в 10:26
поделиться

Алекс Мартелли весит здесь здесь .

Невозможно изменить контейнер (например, dict) при циклическом перемещении по контейнеру. Таким образом, del d[f(k)] может быть небезопасным. Как вы знаете, обходным путем является использование d.items() (для перебора независимой копии контейнера) вместо d.iteritems() (который использует один и тот же базовый контейнер).

Вполне можно изменить значение в существующем индексе dict, но вставка значений в новые индексы (например, d[g(k)]=v) может не работать.

43
ответ дан Community 24 August 2018 в 10:26
поделиться

Вы не можете этого сделать, по крайней мере, с помощью d.iteritems(). Я попробовал это, и Python не работает с

RuntimeError: dictionary changed size during iteration

Если вы используете d.items(), то он работает.

В Python 3, d.items() - это вид в словаре , как d.iteritems() в Python 2. Для этого в Python 3 используйте d.copy().items(). Это также позволит нам перебирать копию словаря, чтобы избежать изменения структуры данных, которую мы итерируем.

16
ответ дан murgatroid99 24 August 2018 в 10:26
поделиться
Другие вопросы по тегам:

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