Как объединить два словаря в одном выражении?

Функция
 function DecimalNumberValidation() {
        var amounttext = ;
            if (!(/^[-+]?\d*\.?\d*$/.test(document.getElementById('txtRemittanceNumber').value))){
            alert('Please enter only numbers into amount textbox.')
            }
            else
            {
            alert('Right Number');
            }
    }

будет проверять любое число в десятичной дроби, которое имеет десятичные числа или нет, оно будет указывать «Правильный номер» другим «Пожалуйста, введите только числа в текстовое поле суммы». появится предупреждающее сообщение.

Спасибо ...:)

4157
задан wim 29 August 2018 в 17:22
поделиться

8 ответов

x = {'a':1, 'b': 2}
y = {'b':10, 'c': 11}
z = dict(x.items() + y.items())
print z

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

54
ответ дан Greg Hewgill 29 August 2018 в 17:22
поделиться

Я хотел что-то подобное, но со способностью определить, как значения на делают дубликаты ключа, были объединены, таким образом, я вырубил это (но в большой степени не протестировал его). Очевидно, это не ни одно выражение, но это - единственный вызов функции.

def merge(d1, d2, merge_fn=lambda x,y:y):
    """
    Merges two dictionaries, non-destructively, combining 
    values on duplicate keys as defined by the optional merge
    function.  The default behavior replaces the values in d1
    with corresponding values in d2.  (There is no other generally
    applicable merge strategy, but often you'll have homogeneous 
    types in your dicts, so specifying a merge technique can be 
    valuable.)

    Examples:

    >>> d1
    {'a': 1, 'c': 3, 'b': 2}
    >>> merge(d1, d1)
    {'a': 1, 'c': 3, 'b': 2}
    >>> merge(d1, d1, lambda x,y: x+y)
    {'a': 2, 'c': 6, 'b': 4}

    """
    result = dict(d1)
    for k,v in d2.iteritems():
        if k in result:
            result[k] = merge_fn(result[k], v)
        else:
            result[k] = v
    return result
100
ответ дан Rainy 29 August 2018 в 17:22
поделиться

Другой, более краткий, опция:

z = dict(x, **y)

Примечание : это стало популярным ответом, но важно указать, что, если y имеет какие-либо нестроковые ключи, то, что это работает вообще, является злоупотреблением деталью реализации CPython, и это не работает в Python 3, или в PyPy, IronPython или Jython. Кроме того, Guido не является поклонником . Таким образом, я не могу рекомендовать эту технику для прямо совместимого или перекрестной реализации портативный код, который действительно означает, что этого нужно избежать полностью.

315
ответ дан Carl Meyer 29 August 2018 в 17:22
поделиться
  • 1
    Да, I' ll редактируют выше с примечанием это we' ve говорил о боксере наилегчайшего веса - действительно, хотя я думаю we' ре сфокусировалось на единице доступа (например, как интерфейс маркера, и осуществляющий контракт на подклассе) - ни один из которых фабрика или статический преобразователь чувствуют, что они получают нас) главная причина я думаю we' ре, не довольное идеей фабрики, это чувствует себя неэлегантным, хотя по общему признанию иногда мы выносим неизящность когда мы can' t придумывают что-то изящное... – jayshao 10 May 2010 в 21:14

Это, вероятно, не будет популярным ответом, но Вы почти наверняка не хотите делать это. Если Вы хотите копию, это - слияние, то используйте копию (или deepcopy, в зависимости от того, что Вы хотите), и затем обновите. Две строки кода намного более читаемы - больше Pythonic - чем однострочное создание с .items () + .items (). Явный лучше, чем неявный.

, Кроме того, при использовании .items () (пред Python 3.0) Вы создаете новый список, который содержит объекты от dict. Если Ваши словари являются большими, то это - довольно много издержек (два больших списка, которые будут выброшены, как только объединенный dict создается). обновление () может работать более эффективно, потому что оно может пробежать второй dict пообъектно.

С точки зрения время :

>>> timeit.Timer("dict(x, **y)", "x = dict(zip(range(1000), range(1000)))\ny=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000)
15.52571702003479
>>> timeit.Timer("temp = x.copy()\ntemp.update(y)", "x = dict(zip(range(1000), range(1000)))\ny=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000)
15.694622993469238
>>> timeit.Timer("dict(x.items() + y.items())", "x = dict(zip(range(1000), range(1000)))\ny=dict(zip(range(1000,2000), range(1000,2000)))").timeit(100000)
41.484580039978027

IMO крошечное замедление между первыми двумя стоит того для удобочитаемости. Кроме того, аргументы ключевого слова в пользу создания словаря был только добавлен в Python 2.3, тогда как копия () и обновление () будет работать в более старых версиях.

193
ответ дан twasbrillig 29 August 2018 в 17:22
поделиться

Альтернатива:

z = x.copy()
z.update(y)
601
ответ дан Matthew Schinckel 29 August 2018 в 17:22
поделиться
  • 1
    Да, иронически ограничение - то, что мы хотим;) Идеально больше соединения - в, но не имея необходимость использовать объект сотрудника - хотя я соглашаюсь, Ваша сводка подобна нашим существующим взглядам и вероятно так же хороша как we' ре, собирающееся быть в состоянии придумать на данный момент. – jayshao 12 May 2010 в 15:34

В Вашем случае, что можно сделать:

z = dict(x.items() + y.items())

Это, поскольку Вы хотите его, поместит финал dict в z и заставит значение для ключа b быть правильно переопределенным вторым (y) значение dict:

>>> x = {'a':1, 'b': 2}
>>> y = {'b':10, 'c': 11}
>>> z = dict(x.items() + y.items())
>>> z
{'a': 1, 'c': 11, 'b': 10}

при использовании Python 3 это только немного более сложно. Создать z:

>>> z = dict(list(x.items()) + list(y.items()))
>>> z
{'a': 1, 'c': 11, 'b': 10}
1546
ответ дан wim 29 August 2018 в 17:22
поделиться
  • 1
    родительская переносная рация! Вы побеждаете меня к нему!:) – les2 10 May 2010 в 20:27

В последующем ответе Вы спросили об относительной производительности этих двух альтернатив:

z1 = dict(x.items() + y.items())
z2 = dict(x, **y)

На моей машине, по крайней мере (довольно обычный x86_64 под управлением Python 2.5.2), альтернатива z2 не только короче и более проста, но также и значительно быстрее. Можно проверить это для себя с помощью timeit модуль, который идет с Python.

Пример 1: идентичные словари, отображающие 20 последовательных целых чисел на себя:

% python -m timeit -s 'x=y=dict((i,i) for i in range(20))' 'z1=dict(x.items() + y.items())'
100000 loops, best of 3: 5.67 usec per loop
% python -m timeit -s 'x=y=dict((i,i) for i in range(20))' 'z2=dict(x, **y)' 
100000 loops, best of 3: 1.53 usec per loop

z2 победы фактором 3,5 или около этого. Различные словари, кажется, приводят к очень отличающимся результатам, но z2 всегда, кажется, выходит вперед. (Если Вы получаете непоследовательные результаты для тот же тест, попытайтесь передать в [1 112] с числом, больше, чем значение по умолчанию 3.)

Пример 2: неперекрывающиеся словари, отображающие 252 коротких строки на целые числа и наоборот:

% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z1=dict(x.items() + y.items())'
1000 loops, best of 3: 260 usec per loop
% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z2=dict(x, **y)'               
10000 loops, best of 3: 26.9 usec per loop

z2 победы приблизительно фактором 10. Это - довольно большая победа в моей книге!

После сравнения тех двух, я задался вопросом, могла ли z1 низкая производительность быть приписана издержкам построения двух списков объекта, которые в свою очередь привели меня задаваться вопросом, могло ли это изменение работать лучше:

from itertools import chain
z3 = dict(chain(x.iteritems(), y.iteritems()))

Несколько быстрых тестов, например,

% python -m timeit -s 'from itertools import chain; from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z3=dict(chain(x.iteritems(), y.iteritems()))'
10000 loops, best of 3: 66 usec per loop

приводят меня приходить к заключению, что z3 несколько быстрее, чем [1 116], но совсем не с такой скоростью, как [1 117]. Определенно не стоящий всего дополнительного ввода.

Это обсуждение все еще пропускает что-то важное, которое является сравнением производительности этих альтернатив с "очевидным" способом объединить два списка: использование update метод. Чтобы попытаться сохранить вещи в равных условиях с выражениями, ни одно из которых не изменяет x или y, я собираюсь сделать копию x вместо того, чтобы изменить его оперативный, следующим образом:

z0 = dict(x)
z0.update(y)

А типичный результат:

% python -m timeit -s 'from htmlentitydefs import codepoint2name as x, name2codepoint as y' 'z0=dict(x); z0.update(y)'
10000 loops, best of 3: 26.9 usec per loop

, Другими словами, z0 и z2, кажется, имею чрезвычайно идентичную производительность. Вы думаете, что это могло бы быть совпадением? Я не делаю....

На самом деле, я пошел бы, насколько утверждать, что для чистого кода Python невозможно сделать немного лучше, чем это. И если можно сделать значительно лучше в дополнительном модуле C, я предполагаю, что люди Python могли бы хорошо интересоваться слиянием кода (или изменение на подходе) в ядро Python. Использование Python dict в большом количестве мест; оптимизация его операций является грандиозным предприятием.

Вы могли также записать это как [1 136]

z0 = x.copy()
z0.update(y)

, как Tony делает, но (не удивительно) различие в нотации, оказывается, не имеет любой измеримый эффект на производительность. Используйте, какой бы ни выглядит правильным Вам. Конечно, он абсолютно корректен, чтобы указать, что версию с двумя операторами намного легче понять.

135
ответ дан the Tin Man 29 August 2018 в 17:22
поделиться

Некоторые способы решить его, не используя модулей Python (никакие зависимости) с немногими строками кодов.

ВСЕ Версии Python (использующий Лямбду):

merge_dicts = lambda old, new: old.update(new) or old

Версия Python> = 3.5:

def merge_dicts(old, new):
    return {**old, **new} 

Более старая Версия Python:

def merge_dicts(old, new):
    merged = old.copy()
    merged.update(new)
    return merged

Этот пример объединится старый и новый при стирании старых значений с новыми значениями.

ИСПОЛЬЗОВАНИЕ:

old = {'name': 'Kevin', 'phone_number': '+33 12 34 45 67'}
new = {'name': 'Kevin', 'phone_number': '+33 88 88 88 88'}

print(merge_dicts(old, new))

ВЫВОД:

{'name': 'Kevin', 'phone_number': '+33 88 88 88 88'}

, ЕСЛИ необходимо иметь дело с кратными числами, объединенными от старого до новой версии, не теряя данных один подход в качестве примера ниже использования массива словарей:

ВСЕ Версии Python:

def merge_dicts(old, news):
    merged = old.copy()
    for new in news:
        merged.update(new)
    return merged

ИСПОЛЬЗОВАНИЕ:

old = {'name': 'Kevin', 'phone_number': '+33 12 34 45 67'}
new_01 = {'name': 'Kevin', 'phone_number': '+33 77 77 77 77', 'age': 28}
new_02 = {'name': 'SabK', 'phone_number': '+33 88 88 88 89'}
new_03 = {'phone_number': '+33 99 99 99 99'}

print(merge_dicts(old, [new_01, new_02, new_03]))

ВЫВОД:

{'phone_number': '+33 99 99 99 99', 'age': 28, 'name': 'SabK'}

В этом примере, новый словарь будет сгенерирован от старого (первый аргумент) и затем обновит последовательно от первого элемента массива к последнему (new_01> new_02> new_03)

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

0
ответ дан 17 December 2019 в 16:00
поделиться
Другие вопросы по тегам:

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