Проверьте, существует ли значение во вложенных списках - PullRequest
2 голосов
/ 17 марта 2009

в моем списке:

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

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

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

Ответы [ 6 ]

6 голосов
/ 17 марта 2009

Вы используете неправильный тип данных. Используйте dict из set 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)
4 голосов
/ 17 марта 2009

Исходя из решения рекурсии, в 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')
4 голосов
/ 17 марта 2009

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

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

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

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

Он создаст ключ 'dog', если он не существует, и так как setdefault возвращает набор, который либо существует, либо был только что создан, вы можете добавить действие прикуса. Устанавливает, что нет дубликатов автоматически.

0 голосов
/ 17 марта 2009

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

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 является неизбежным следствием вашей структуры данных, поэтому все советуют вместо этого рассматривать словари.

0 голосов
/ 17 марта 2009

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

Вы можете улучшить свой код следующим образом:

if not any((animal[0] == "bird") for animal in animals):
    # append "bird" to animals
0 голосов
/ 17 марта 2009
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 - nice one @recursive)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...