2015-09-21 2 views
2

У меня есть список из 200 тыс. Элементов. Этими элементами являются 7 разных меток (на самом деле это список фруктов). Мне нужно назначить число для каждого фрукта.Любой быстрый способ маркировки списка в Python?

Есть ли быстрый способ сделать это?

Я написал это до сих пор .. и это занимает много времени.

dic,i = {},0.0 
for idx,el in enumerate(listFruit): 
    if dic.has_key(el) is not True: 
     dic[el] = i 
     i+=1.0 
    listFruit[idx] = dic[el] 
+0

Вы имеете в виду вы хотите присвоить уникальный номер каждого плода? –

+0

Да. Apple должна быть 1 всегда, Банан 2 Клубника 3 .... до ananas 7. –

+1

Примечание: 'has_key' устарел. Чтобы проверить, используется ли ключ в словаре, используйте «ключ в словаре». В вашем случае: 'if el not in dic'. Также я понятия не имею, почему вы назначаете числа с плавающей запятой .... – Bakuriu

ответ

5

Используйте collections.defaultdict() object с itertools.count() object соорудили, чтобы произвести следующее значение в качестве завода; это позволит избежать необходимости тестировать каждый ключ самостоятельно, а также увеличивать вручную.

Затем используйте список понимание, чтобы поместить эти цифры в списке:

from collections import defaultdict 
from functools import partial 
from itertools import count 

unique_count = defaultdict(partial(next, count(1))) 
listFruit[:] = [unique_count[el] for el in listFruit] 

functools.partial() callable создает оболочку вокруг next() function, чтобы гарантировать, что код работает в любом Python 2 или Python 3.

Я использовал здесь целочисленный счет, начиная с 1. Вы можете заменить count(1) на count(1.0), если вы настаиваете на наличии значений с плавающей запятой; вы получите 1.0, 2.0, 3.0 и т. д. вместо этого.

Демо:

>>> from collections import defaultdict 
>>> from functools import partial 
>>> from itertools import count 
>>> from random import choice 
>>> fruits = ['apple', 'banana', 'pear', 'cherry', 'melon', 'kiwi', 'pineapple'] 
>>> listFruit = [choice(fruits) for _ in xrange(100)] 
>>> unique_count = defaultdict(partial(next, count(1))) 
>>> [unique_count[el] for el in listFruit] 
[1, 2, 3, 2, 4, 5, 6, 7, 1, 2, 4, 6, 3, 7, 3, 4, 5, 2, 5, 7, 3, 5, 1, 3, 3, 5, 2, 2, 6, 4, 6, 2, 1, 1, 3, 6, 6, 4, 7, 2, 6, 4, 5, 2, 1, 7, 7, 7, 4, 3, 7, 3, 1, 1, 5, 3, 3, 6, 5, 6, 1, 4, 3, 7, 2, 7, 7, 4, 7, 1, 4, 3, 7, 3, 4, 5, 1, 5, 5, 1, 5, 6, 3, 4, 3, 1, 1, 1, 5, 7, 2, 2, 6, 3, 6, 1, 1, 6, 5, 4] 
>>> unique_count 
defaultdict(<functools.partial object at 0x1026c5788>, {'kiwi': 4, 'apple': 1, 'cherry': 5, 'pear': 2, 'pineapple': 6, 'melon': 7, 'banana': 3}) 
+0

'partial (next, count (1))' работает как в python2, так и 3. Или 'lambda: next (count (1))' – Bakuriu

+0

@Bakuriu: да, спасибо. Я обсуждал вопрос о том, чтобы не усложнять ситуацию здесь (с точки зрения когнитивной нагрузки). Я предпочитаю 'partial()', так как он слишком сильно отказывается от кода Python. –

+0

Подождите лямбда, нужно быть 'c = count (1); lambda: next (c) 'в противном случае это постоянная функция – Bakuriu

0
fruit_list = ['apple', 'banana', 'strawberry', 'watermelon','apple','watermelon'] 

unique_fruits = [x for x in set(fruit_list)] 
fruit_dict = dict((unique_fruits[y],y) for y in range(len(unique_fruits))) 
result = [(x, fruit_dict.get(x)) for x in fruit_list if x in fruit_dict.keys()] 

Что-то подобное?

Результат: [('apple', 2), ('banana', 3), ('strawberry', 0), ('watermelon', 1), ('apple', 2), ('watermelon', 1)]

Или result = [fruit_dict.get(x) for x in fruit_list if x in fruit_dict.keys()]

Результат - [2, 3, 0, 1, 2, 1]

Смежные вопросы