2016-04-20 3 views
1

есть лучший способ сделать это ...? Я чувствую, что так много для Не может быть хорошим.Слишком много для X в Y

Обратите внимание, что ListaOnline - это просто список имен пользователей, и эти имена пользователей обычно имеют [] символы в своих псевдонимах. Надеюсь, это не смущает.

ListaOnline = ['[YOLO]someone', 'Another person', 'example'] 
ListaJugadores = [['[YOLO]someone', ['healer', 'tank']], ['example', ['healer', 'dps']]] 
ListaMeta = Lista Meta: ['healer', 'tank', 'dps', 'dps', 'dps', 'support', 'support'] 
ListaResultado = [['healer', []], ['tank', []], ['dps', []], ['dps', []], ['dps', []], ['support', []], ['support', []]] 
for i in ListaOnline: #for each player online 
    for j in ListaJugadores: #check players in database 
     if j[0] == i: #and if found 
      for k in ListaMeta: #for each role in the Meta 
       for l in j[1]: #for each item in player's roles 
        if k in l: #if the player has this role 
         for m in ListaResultado: #for each role in ListaResultado 
          if k in m: #if the role matches 
           m[1].append(i) #add player to the list 
print(str(ListaResultado)) 

>>> [['healer', ['[YOLO]someone', 'example']], ['tank', ['[YOLO]someone']], ['dps', ['example']], ['dps', []], ['dps', []], ['support', []], ['support', []]] 

Ожидаемый результат - получить список с каждым игроком, добавленным к ролям, которые они сохраняют в базе данных. Списки ListaOnline, ListaJugadores и ListaMeta будут меняться каждый день, поэтому каждый раз, когда этот код запускается, нужно будет проверять наличие новых ролей и заполнять ListaResultado в соответствии с ожидаемыми ролями в мета.

+4

Похоже, что вы должны использовать словари вместо списков списков с ключом в качестве первого элемента списка. – eguaio

+0

С его взглядом ваш код должен быть запущен как работа cron или что-то подобное, правильно ли я понимаю ваше требование? –

+0

Предполагается, что это будет добавлено в качестве команды для бота TeamSpeak. Игроки могут использовать команду для сохранения своих ролей в базе данных. Администратор может использовать другую команду для сохранения разных мета-списков. Администратор может использовать другую команду, которая создает список всех пользователей в Интернете, которые могут вписаться в роль (этот код), а затем бот должен сказать им, какую роль использовать, чтобы сделать наиболее оптимальную композицию, но эта часть еще не закончена. – Saelyth

ответ

1

Что-то вроде этого может упростить ваш код.

ListaOnline = ['[YOLO]someone', 'Another person', 'example'] 
DictJugadores = {'[YOLO]someone': ['healer', 'tank'], 'example': ['healer', 'dps'] } 
ListaMeta = ['healer', 'tank', 'dps', 'dps', 'dps', 'support', 'support'] 
DictResultado = dict((role, []) for role in ListaMeta) 
for user in ListaOnline: #for each player online 
    if user in DictJugadores: 
     for role in DictJugadores[user]: 
      DictResultado[role].append(user) 
print(str(DictResultado)) 

Даст вам:

{'healer': ['[YOLO]someone', 'example'], 'support': [], 'tank' : ['[YOLO]someone'], 'dps': ['example']} 

И если вы не знаете, как преобразовать списки dicts:

def convert_list_to_dict(list_with_keys): 
    d = {} 
    for l in list_with_keys: 
     d[l[0]] = l[1] 
    return d 

И в обратном направлении:

def convert_dict_to_list(my_dict): 
    l = [] 
    for k, v in my_dict.iteritems(): 
     l.append([k,v]) 
    return l 

Вы также можете использовать python nice list a й синтаксис dicts сахар, чтобы получить работу в одной строке:

DictResultado = dict((r, [u for u in ListaOnline 
          if u in DictJugadores and r in DictJugadores[u]]) 
         for r in ListaMeta) 

(Это также злоупотребление питона ленивых вычислений в и выражения, чтобы избежать исключения KeyError в словаре. То есть, порядок в if u in DictJugadores and r in DictJugadores[u] действительно имеет значение).

Но я бы пошел с решением for loop, так как он стал более понятным и понятным. Как Написание твердого кода книга рекомендует, вы должны сделать чистый и скучный код и попытаться не злоупотреблять конкретным синтаксисом языка.

Кстати, я настоятельно рекомендую вам попробовать следовать за pep 8 в вашем коде.

1
ListaJugadores = [['[YOLO]someone', ['healer', 'tank']], ['example', ['healer', 'dps']]] 

Может быть лучше представлены:

ListaJugadores = {'[YOLO]someone': ['healer', 'tank'], 'example': ['healer', 'dps']} 

Этот способ полезен: теперь вы можете сделать Lookups:

> ListaJugadores['[YOLO]someone] 
> ['healer', 'tank'] 

Это словарь, и это в конечном итоге может быть расширена. Может быть, вы хотите, чтобы включить немного больше информации:

ListaJugadores = {'[YOLO]someone': {'roles': ['healer', 'tank'], 'last_login': '01-01-1990'}} 

Среда для поисков также O (1), который ... очень приятно. :)

Это не дает вам пути туда. Если вы хотите создать свой ListaResultado объект, вы все равно должны сделать что-то вроде ..

ListaResultado = {'healer': [], 'tank': [], 'dps': []} 

for user in ListaOnline: 
    if user in DictJugadores: 
     for role in DictJugadores[user]: 
      ListaResultado[role].append(user) 

Однако, в конце концов, было бы лучше, чтобы переместить это в реляционную базу данных. Затем вы можете просто запросить всех онлайн-пользователей и получить их роли!Это было бы очень просто, и он перемещает вашу модель данных в безопасное место.

Кроме того, поскольку вы изучаете: смотрите руководства по стилю PEP8. Соглашение Python должно использовать имена переменных under_score :)

+1

Если вы посмотрите на что-то вроде sqlalchemy, вы можете избежать попадания во все внутренние элементы SQL и сделать ваш код DB агностиком. – Holloway

+0

Yup, ORM - хорошее место для начала! PeeWee - очень легкий и простой в освоении. –

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