Условное выражение, рассчитывающее в Python

Невозможно сделать это в одном запросе. Вы должны искать документ в первом запросе:

Если существует документ:

db.bar.update( {user_id : 123456 , "items.item_name" : "my_item_two" } , 
                {$inc : {"items.$.price" : 1} } , 
                false , 
                true);

Else

db.bar.update( {user_id : 123456 } , 
                {$addToSet : {"items" : {'item_name' : "my_item_two" , 'price' : 1 }} } ,
                false , 
                true);

Не нужно добавлять условие {$ne : "my_item_two" } .

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

25
задан nicolaum 19 November 2009 в 19:14
поделиться

3 ответа

sum(x.b == 1 for x in L)

Логическое (как результат сравнений, таких как x.b == 1) также является int, со значением 0 для False, 1 для True, поэтому арифметика, такая как суммирование работает просто отлично.

Это самый простой код, но, возможно, не самый быстрый (наверняка вам скажет только timeit ;-). Рассмотрим (упрощенный случай, чтобы хорошо вписаться в командные строки, но эквивалентно):

$ py26 -mtimeit -s'L=[1,2,1,3,1]*100' 'len([x for x in L if x==1])'
10000 loops, best of 3: 56.6 usec per loop
$ py26 -mtimeit -s'L=[1,2,1,3,1]*100' 'sum(x==1 for x in L)'
10000 loops, best of 3: 87.7 usec per loop

Таким образом, для этого случая «расточительный в памяти» подход генерации дополнительного временного списка и проверки его длины на самом деле значительно быстрее чем более простой, короткий, бережливый к памяти, который я предпочитаю. Разумеется, другие комбинации значений списка, реализации Python, доступность памяти для «ускорения» этого ускорения и т. Д. Могут, конечно, повлиять на точную производительность.

43
ответ дан Alex Martelli 15 October 2019 в 15:35
поделиться

Я бы предпочел второй, так как он перебирает список только один раз.

Если вы используете count(), вы перебираете список один раз, чтобы получить значения b, а затем снова зацикливаете его, чтобы увидеть, сколько из них равно 1.

Аккуратный способ может использовать reduce():

reduce(lambda x,y: x + (1 if y.b == 1 else 0),list,0)

Документация говорит нам, что reduce() будет:

Применить функцию два аргумента в совокупности с элементами итерируемого слева направо, чтобы свести итерируемое к одному значению.

Таким образом, мы определяем lambda, который добавляет одно накопленное значение, только если атрибут элемента списка b равен 1.

2
ответ дан Dave Webb 15 October 2019 в 15:35
поделиться
print sum(1 for e in L if e.b == 1)
15
ответ дан 28 November 2019 в 06:39
поделиться
Другие вопросы по тегам:

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