LINUX.ORG.RU

Как в питоне словарь внутри себя использовать

 


0

1

Чего-то не понял в нем.

list=['a','a','a','b','c','c','c','c']
s = {i: s[i]+1 for i in list}
print(s)

Хотелось бы увидеть вывод вроде 'a':3, 'b':1, 'c':4 но возникает ошибка «NameError: name 's' is not defined» Если же просто присваивать допустим 1 каждому ключу, то нормально, но мне не это нужно.

★★★★★

Последнее исправление: praseodim (всего исправлений: 2)

;)

s=__import__('collections').Counter(list)
(s:={},{s.__setitem__(i,s.get(i,0)+1)for i in list})

Приятного аппетита гурман!

qulinxao3 ★☆
()

(s:={},{s.__setitem__(i,s.get(i,0)+1)for i in list})

Ну и говно. И после этого они что-то говорят на жс.

list.reduce((s, v)=>{
  s[v] = s[v] || 0;
  s[v]++;
  return s;
}, {})

crutch_master ★★★★★
()

У тебя проблема - ты используешь s до того как его заассигнил (s у тебя определяется после окончания вычисления выражения)

Условно это расписывается как

push {i: s[i] + 1 for i in let} ; pop s

Соотвественно, у тебя при вычислении выражения получается тыква.

no-dashi-v2 ★★★★
()
Ответ на: комментарий от crutch_master

топик же явно троляка

поэтому пусть поест

ваще точнее будет:


print(f'{(s:={},{s.__setitem__(i,s.get(i,0)+1)for i in list})[0]}'[1:-1])
qulinxao3 ★☆
()
Ответ на: комментарий от Zeta_Gundam

Через цикл как-то грубо и не изящно. В питоне такие вещи обычно как-то в одну строчку записываются.

praseodim ★★★★★
() автор топика

Это довольно не оптимально, но вот ещё:

l=['a','a','a','b','c','c','c','c']
s = { c: l.count(c) for c in l }
print(s)
{'a': 3, 'b': 1, 'c': 4}

anonymous
()
Ответ на: комментарий от no-dashi-v2

1. у него проблемы нет, больше того проблема не у него

называть список list это явно не спроста

чел хочет знать как использовать словарь в этом же словаре

чел узнаёт

qulinxao3 ★☆
()
Ответ на: комментарий от anonymous

не не не

чел стремится использовать значения по ключу из словаря при формировании этого же словаря - питон может в такое - это не значит что так надо

но если нет времени учиться то ок

qulinxao3 ★☆
()
Ответ на: комментарий от praseodim

Мне сейчас звонил Гуидо, сказал что в дзен забыли добавить строчку: «Простое лучше, чем изящное».

Zeta_Gundam
()
Ответ на: комментарий от no-dashi-v2

У тебя проблема - ты используешь s до того как его заассигнил (s у тебя определяется после окончания вычисления выражения)

А, блин и в самом деле. Но это не спасает.

list=sorted(['a','a','a','b','c','c','c','c'])
s = {}
s = {i: s[i]+1 for i in list}
print(s)

Результат трейсбеки и KeyError: 'a' ну и вправду, значение-то не определено вначале. Ok. Присвоил всем нули сначала. Уже коряво как-то

list=sorted(['a','a','a','b','c','c','c','c'])
s = {i: 0 for i in list}
s = {i: s[i]+1 for i in list}
print(s)

Результат все единички

{'a': 1, 'b': 1, 'c': 1}

Кажется +1 в генераторе понялось как-то не так.

praseodim ★★★★★
() автор топика

мне не это нужно

А что тебе нужно? Посчитать количество вхождений каждого символа?

Nervous ★★★★★
()
Ответ на: комментарий от praseodim

в одну строчку:


print(f'{(list:=list("aaabcccc"),s:={},{s.__setitem__(i,s.get(i,0)+1)for i in list},list:=type([]))[1]}'[1:-1])

qulinxao3 ★☆
()
Ответ на: комментарий от rtxtxtrx

Хотя undefined | 0 - это неочевидное приведение к числу, опять же к нулю

Так, наверное, понятнее:

['a','a','a','b','c','c','c','c'].reduce((a, b) => (a[b]=(++a[b]||1),a), {})

++undefined===NaN, а NaN || x всегда x

rtxtxtrx ★★★
()
Ответ на: комментарий от rtxtxtrx

Жаль в пистоне так нельзя. Вот можно было бы в питоне километровые однострочники печатать - цены бы ему не было

rtxtxtrx ★★★
()
Ответ на: комментарий от qulinxao3

чел стремится использовать значения по ключу из словаря при формировании этого же словаря - питон может в такое - это не значит что так надо

Проблема в том, что в таком неизящном перле тут вообще проблем нет


my @list = ("a","a","a","b","c","c","c","c");
my %hash = ();

foreach $k (@list)
{
  $hash{$k}++;  
}

print %hash;

praseodim ★★★★★
() автор топика
Ответ на: комментарий от rtxtxtrx

Ага, а потом dict от Counter

s = dict(c)

Это уже на что-то похоже, но плохо, что элементарную вещь надо или через цикл делать или как-то через сторонние функции.

praseodim ★★★★★
() автор топика
Ответ на: комментарий от qulinxao3

для обновления s [ i ]:=

Это как:

s = {s: s+1 for i in list} дает эффект {0: 1} в результате. Присваивание в паскалевском стиле тут вообще ошибочно.

praseodim ★★★★★
() автор топика
Ответ на: комментарий от praseodim

блин:

второй однострок из Как в питоне словарь внутри себя использовать (комментарий)

делает ровно то что вы хотели ровно так как вы написали:

1. создаётся пустой словарь и ему даётся имя

2. для каждого значения из списка инкрементируется по этому ключу с дефолтом нуль сч>тчик

зы

если использовать defaultdict то 2 чуть короче

а вообще для этого в стандаротной либе есть Counter в collections - это первый однострок - модуль collections сырец читабельный

qulinxao3 ★☆
()
Ответ на: комментарий от praseodim

продолжайте тролить

в py3 с py3.6? есть операция моржик позволяющая инициализировать имя значением внутри выражения

и это реально достаточное основание для отставки с поста добродушного диктатора

ибо позволяет писать очень плохой код

qulinxao3 ★☆
()
Ответ на: комментарий от praseodim

Разупорись, а. Сначала dict comprehension создаёт новый словарь, а только потом присваивает его s.

t184256 ★★★★★
()
Ответ на: комментарий от praseodim

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

l = [‘a’, ‘b’, ‘c’, ‘c’, ‘b’]

s = dict()

s = {i: s.update({i: s.get(i, 0) + 1}) or s[i] for i in l}

print(«%s» % s)

{‘a’: 1, ‘b’: 2, ‘c’: 2}

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

В общем долбанутому запросу долбанутое решение

no-dashi-v2 ★★★★
()
Ответ на: комментарий от rtxtxtrx

можно

делаем контейнер - список али кортеж

его элементы инициализация через моржик локальных имён

по мере вычисления вот этого обьемлющего контейнера можно в следующих выражениях использовать имена ранее вычисленных выражений

и всё

т.е всю программу можно написать как один большой кортеж - с рекурсией и следовательно это полная по тьюрингу

qulinxao3 ★☆
()
Ответ на: комментарий от no-dashi-v2

В общем долбанутому запросу долбанутое решение

Ну почему долбанутому. Получается пока или Counter - изящно или просто самому в цикле считать - неизящно, но понятно, если нет времени искать как правильно.

praseodim ★★★★★
() автор топика

что только люди не делают, лишь бы монады не изучать

caryoscelus
()
Ответ на: комментарий от qulinxao3

какое паскалевское?! это walrus

There is new syntax := that assigns values to variables as part of a larger expression. It is affectionately known as “the walrus operator” due to its resemblance to the eyes and tusks of a walrus.

Непонятно как в питоне в данном случае его использовать:

s = {i: s[i]:=s[i]+1 for i in list}

Invalid Syntax

s = {s[i]:=s[i]+1 for i in list}

SyntaxError: cannot use assignment expressions with subscript

praseodim ★★★★★
() автор топика
Ответ на: комментарий от qulinxao3

print(f'{(s:={},{s.__setitem__(i,s.get(i,0)+1)for i in list})[0]}'[1:-1])

В общем, тоже конечно решение, но какое-то не очень красивое. А вот это [1:-1] вообще фишка питона получается - вылезло расширение массива.

praseodim ★★★★★
() автор топика
Ответ на: комментарий от praseodim

[ 1 : - 1 ] это шутка ибо в стартовом без фигурных скобок

qulinxao3 ★☆
()
Ответ на: комментарий от qulinxao3

Спасибо. Проблема, что вот как начинающий в питоне до этого просто не додумался бы самостоятельно. Или спустя очень многие часы поисков.

То ли я что-то не то делаю. Но питон для меня на каждом шагу контринтуитивный язык, как-то не получается в него никак въехать. Помню в перл, в c# въезжал быстро, сложные вещи конечно не сразу, но все-таки.

А с питоном у меня все время или что-то совсем тривиальное или если посложнее, то или писать в стиле Си (проблему со словарем мог просто циклами вручную решить) или долго тупить.

praseodim ★★★★★
() автор топика
Ответ на: комментарий от crutch_master

Нет, оно уже готово, в стандартной библиотеке и оптимальное. Дальше можно только изголяться с Cython или на другой язык переходить.

ac130kz ★★
()
l=list('aaabcccc')

серь>зно: 1.

from collections import Counter
s=Counter(l) # 
2.
from collections import defaultdict
s=defaultdict(int)
for a in l:s[a]+=1
3.
s={}
for a in l:
    if a not in s:s[a]=0
    s[a]+=1

    

qulinxao3 ★☆
()
Ответ на: комментарий от ac130kz

Ну так я про то и говорю, что для задачи x есть y. Я промолчу о том, почему такой подход - говно, думаю это очевидно, если хоть немного понимать теорию множеств.

crutch_master ★★★★★
()
Ответ на: комментарий от crutch_master

Так l.count(x) - это же каждый раз проход по массиву и сложность n^2

Я знаю.

anonymous
()
Ответ на: комментарий от praseodim

Но питон для меня на каждом шагу контринтуитивный язык

Для тебя «контринтуитивно» что переменная должна быть инициализирована прежде чем использована? Ну тогда у меня для тебя плохие новости.

no-dashi-v2 ★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.