2009-03-16 3 views
2

в моем списке:Проверьте, если значение существует в вложенных списках

animals = [ ['dog', ['bite'] ], 
      ['cat', ['bite', 'scratch'] ], 
      ['bird', ['peck', 'bite'] ], ] 

add('bird', 'peck') 
add('bird', 'screech') 
add('turtle', 'hide') 

Функции добавь следует проверить, что животное и действия не были добавлены перед добавлением их в список. Есть ли способ сделать это, не вложив петлю для каждого шага в список?

ответ

4

Хотя можно построить родовое функция, которая находит животное в списке, используя a.index или испытывая «собаку» на животных, вам действительно нужен словарь здесь, иначе функция добавления будет ужасно масштабироваться, так как больше животные добавлено:

animals = {'dog':set(['bite']), 
      'cat':set(['bite', 'scratch'])} 

Вы можете затем «один выстрел» функция добавить с помощью SetDefault:

animals.setdefault('dog', set()).add('bite') 

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

6

Вы используете неправильный тип данных. Используйте dictset из S вместо:

def add(key, value, userdict): 
    userdict.setdefault(key, set()) 
    userdict[key].add(value) 

Использование:

animaldict = {} 
add('bird', 'peck', animaldict) 
add('bird', 'screech', animaldict) 
add('turtle', 'hide', animaldict) 
+0

Если userdict является сборником.defaultdict (set), тогда вы можете опустить вызов setdefault - проще понять IMHO. –

+0

setdefault возвращает существующее или созданное значение. Вы можете использовать userdict.setdefault (key, set()). Add (value) или сохранить его в переменной для удобочитаемости. –

0
animals_dict = dict(animals) 

def add(key, action): 
    animals_dict.setdefault(key, []) 
    if action not in animals_dict[key]: 
     animals_dict[key].append(action) 

(Обновлено использовать setdefault - хороший один @recursive)

0

Вы действительно должны использовать словарь для этой цели. Или, альтернативно, класс Animal.

Вы могли бы улучшить свой код так:

if not any((animal[0] == "bird") for animal in animals): 
    # append "bird" to animals 
4

на основе решения рекурсивные, в в Python 2.5 или более поздней версии вы можете использовать defaultdict класс, что-то вроде этого:

from collections import defaultdict 

a = defaultdict(set) 

def add(animal, behavior): 
    a[animal].add(behavior) 

add('bird', 'peck') 
add('bird', 'screech') 
add('turtle', 'hide') 
0

Хотя я согласен с другими. ваш выбор структуры данных, здесь есть ответ на ваш вопрос:

def add(name, action): 
    for animal in animals: 
     if animal[0] == name: 
      if action not in animal[1]: 
       animal[1].append(action) 
      return 
    else: 
     animals.append([name, [action]]) 

Цикла for является неизбежным следствием вашей структуры данных, поэтому каждый советует вам рассмотреть словари вместо.