2013-06-10 1 views
1

У меня есть два списка: один содержит продукты, а другой содержит связанные цены. Списки могут содержать неопределенное количество продуктов. Примером списков будет что-то вроде:Обработка данных в списках с дубликатами в Python

  • Продукты: [ «Яблоко», «Яблоко», «Яблоко», «Orange», «банан», «банан», «Персик», «Ананас» , 'Ананас']
  • Цены: [ '1.00', '2.00', '1.50', '3.00', '0.50', '1.50', '2.00', '1.00', '1.00']

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

Нужные окончательные списки будет что-то вроде:

  • Продукты: [ 'Яблоко', 'Orange', 'банан', 'Персик', 'Ананас']
  • Цены: [ '1,00 ',' 3.00 ',' 0.50 ',' 2.00 ',' 1.00 ']

Я хотел бы узнать, как наиболее эффективный способ сделать это в Python. Спасибо

ответ

3
from collections import OrderedDict 
products = ['Apple', 'Apple', 'Apple', 'Orange', 'Banana', 'Banana', 'Peach', 'Pineapple', 'Pineapple'] 
prices = ['1.00', '2.00', '1.50', '3.00', '0.50', '1.50', '2.00', '1.00', '1.00'] 

min_prices = OrderedDict() 
for prod, price in zip(products, prices): 
    min_prices[prod] = min(float(price), min_prices.get(prod, float('inf'))) 

>>> print min_prices.keys(), min_prices.values() 
['Apple', 'Orange', 'Banana', 'Peach', 'Pineapple'] [1.0, 3.0, 0.5, 2.0, 1.0] 
+0

прохладное 'min' функция – mshsayem

+0

+1 - Это самый лучший способ – dawg

+0

отлично - спасибо – LaGuille

1

Наверное, самый простой способ воспользоваться исполнения словарей уникальных ключей:

from operator import itemgetter 
Products = ['Apple', 'Apple', 'Apple', 'Orange', 'Banana', 'Banana', 'Peach', 'Pineapple', 'Pineapple'] 
Prices = ['1.00', '2.00', '1.50', '3.00', '0.50', '1.50', '2.00', '1.00', '1.00'] 

final = dict(sorted(zip(Products, Prices), key=itemgetter(1), reverse=True)) 
+0

Однострочное программирование зашло слишком далеко. – morningstar

+0

Я так не думаю; это относительно просто.Если вы предпочитаете, вы можете разбить его на несколько строк, хранящихся в переменных, но в конечном счете это все же проще, чем создание функции или использование цикла 'for' или anythign вроде этого – jdotjdot

+0

. Я не согласен, ваш путь требует, чтобы читатель был знаком с dict , zip, отсортированные, ключевые и обратные необязательные аргументы и itemgetter. В то время как другой ответ использует примерно столько стандартных символов библиотеки, они в основном из основного 20 наиболее используемых, тогда как itemgetter, вероятно, не входит в топ-100. Меньше символов! = Более читаемо. – morningstar

0

не кратчайшее решение, но оно иллюстрирует точку: Предположим, что ваши списки products и prices, соответственно. Тогда:

lookup = dict()  
for prod, price in zip(products, prices): 
    if prod not in lookup: 
     lookup[prod] = price 
    else: 
     lookup[prod] = min(price, lookup[prod]) 

На данный момент, lookup ДИКТ содержит каждый из ваших продуктов, и его минимальная цена. Разумеется, дикт - лучшая структура данных для этого, чем два списка; если вы действительно хотите, чтобы это как два отдельных списков вместо этого, вы можете сделать что-то вроде этого:

new_prods = [] 
new_prices = [] 
for prod, price in lookup.items(): 
    new_prods.append(prod) 
    new_prices.append(price) 
1

Что об этом:

prices = map(float,prices) 
r={} 
for k,v in zip(products,prices): 
    if v < r.setdefault(k,float('inf')): 
     r[k] = v 
products,prices = r.keys(),map(str,r.values()) 
+1

Вы не должны использовать 'sys.maxint' использование' float ('inf') ' – jamylak

+0

Thanks; не знаю, что – mshsayem

0
>>> from collections import OrderedDict 
>>> products = ['Apple', 'Apple', 'Apple', 'Orange', 'Banana', 'Banana', 'Peach', 'Pineapple', 'Pineapple'] 
>>> prices = ['1.00', '2.00', '1.50', '3.00', '0.50', '1.50', '2.00', '1.00', '1.00'] 
>>> dic = OrderedDict() 
>>> for x,y in zip(products,prices): 
...  dic.setdefault(x, []).append(y) 
...  
>>> dic.keys() 
['Apple', 'Orange', 'Banana', 'Peach', 'Pineapple'] 
>>> [min(val, key = float) for val in dic.values()] 
['1.00', '3.00', '0.50', '2.00', '1.00'] 
0

Вы можете использовать словарь, чтобы сделать это:

Products = ['Apple', 'Apple', 'Apple', 'Orange', 'Banana', 'Banana', 'Peach', 'Pineapple', 'Pineapple'] 
Prices = ['1.00', '2.00', '1.50', '3.00', '0.50', '1.50', '2.00', '1.00', '1.00'] 

Prices=[float(price) for price in Prices] 

di={} 
for prod,price in zip(Products,Prices): 
    di.setdefault(prod,[]).append(price) 

for key,val in di.items(): 
    di[key]=min(val) 

print di 

Печать {'Orange': 3.0, 'Pineapple': 1.0, 'Apple': 1.0, 'Peach': 2.0, 'Banana': 0.5}

Если вы хотите два списка в том же порядке, вы можете сделать это:

from collections import OrderedDict 

new_prod=OrderedDict.fromkeys(Products).keys() 
new_prices=[di[item] for item in new_prod] 

Печать:

['Apple', 'Orange', 'Banana', 'Peach', 'Pineapple'] 
[1.0, 3.0, 0.5, 2.0, 1.0] 
+0

ваша функция 'uniq' устарела, в настоящее время идиомой является' OrderedDict.fromkeys (seq) .keys() ', которая не использует' not seen_add (x) 'hack – jamylak

+0

@jamylak: Спасибо. Исправлена – dawg