Как заменить элементы в подсписке условно. - PullRequest
0 голосов
/ 01 ноября 2018

Я пытаюсь сгенерировать список внутри списка. Я перебираю файл, чтобы обновить список, если один элемент подсписка больше. Я написал этот код:

targets = open(file)

longest_UTR = []

for line in targets:

    chromosome, locus, mir, gene, transcript, UTR_length = line.strip("\n").split("\t")

    length_as_integer = int(UTR_length)

    if not any(x[:3] == [locus, mir, gene] for x in longest_UTR):

        longest_UTR.append([locus, mir, gene, transcript, length_as_integer])

    elif length_as_integer > [int(x[4]) for x in longest_UTR]: ##x[4] = previous length_as_integer

        longest_UTR.append([locus, mir, gene, transcript, length_as_integer])

print (longest_UTR)

Однако я получаю эту ошибку:

elif len_as_int > (int(x[4]) for x in longest_UTR):

TypeError: '>' not supported between instances of 'int' and 'generator'

Как я могу преобразовать x[4] в целое число, чтобы сравнить с length_as_integer?

Спасибо

Ответы [ 3 ]

0 голосов
/ 01 ноября 2018

Итак, было немного назад и вперед относительно ваших требований, но мое окончательное понимание таково: Вы зацикливаетесь на наборе данных. Каждый target в этом наборе данных имеет атрибуты locus, mri и gene, а также атрибут UTR_length. Для каждой уникальной комбинации locus, mri и gene вы пытаетесь найти все targets, которые имеют максимум UTR_Length?

Учитывая, что вы хотите найти максимальное значение в наборе данных, есть два подхода.
1) Вы можете просто преобразовать ваш входной файл в кадр данных pandas, сгруппировать по значениям locus, mri и gene и вернуть все значения с максимальным значением (UTR_Length). Из-за простоты реализации это, вероятно, ваш лучший выбор. Тем не менее, панды не всегда являются правильным инструментом и несут много накладных расходов, особенно если вы хотите докеризировать свой проект.

2) Если вы хотите использовать базовые пакеты Python, я бы порекомендовал воспользоваться наборами и словарями:

targets = open(file)
list_of_targets = []    
for line in targets:

          chromosome, locus, mir, gene, transcript, UTR_length = line.strip("\n").split("\t")
          length_as_integer = int(UTR_length)

          list_of_targets.append((chromosome, locus, mir, gene, transcript, UTR_length))

# Generate Set of unqiue locus, mri, gene (lmg) combinations
set_of_locus_mri_gene = {(i[1], i[2], i[3]) for i in list_of_targets}

# Generate dictionary of maximum lengths for each distinct lmg combo
dict_of_max_lengths = {lmg: max([targets[5] for targets in list_of_targets if 
                                    (targets[1], targets[2], targets[3]) == lmg]) for 
                                    lmg in set_of_locus_mri_gene}

# Generate dictionary with lmg keys and all targets with corresponding max length
final_output = {lmg: [target for target in list_of_targets if target[5] == max_length] for
                        lmg, max_length in dict_of_max_lengths.items()}
0 голосов
/ 01 ноября 2018

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

targets = open(file)
longest_UTR = {}

for line in targets: 
    chromosome, locus, mir, gene, transcript, UTR_length = line.strip("\n").split("\t")    
    length_as_integer = int(UTR_length)

    # Your condition works for initializing the dictionary because of the default value.
    if length_as_integer > longest_UTR.get("Length", -1):
        longest_UTR["Chromosome"] = chromosome
        longest_UTR["Locus"] = locus
        longest_UTR["Mir"] = mir
        longest_UTR["Gene"] = gene
        longest_UTR["Transcript"] = transcript
        longest_UTR["Length"] = length_as_integer

print (longest_UTR)

Редактировать: здесь также версия кода с использованием списка, на случай, если вам интересно увидеть разницу. Лично я нахожу очиститель словаря подходящим для чтения.

targets = open(file)
longest_UTR = [None, None, None, None, None, -1]

for line in targets: 
    chromosome, locus, mir, gene, transcript, UTR_length = line.strip("\n").split("\t")    
    length_as_integer = int(UTR_length)

    # Your condition works for initializing the list because of the default value.
    if length_as_integer > longest_UTR[5]:
        longest_UTR[0] = chromosome
        longest_UTR[1] = locus
        longest_UTR[2] = mir
        longest_UTR[3] = gene
        longest_UTR[4] = transcript
        longest_UTR[5] = length_as_integer

print (longest_UTR)
0 голосов
/ 01 ноября 2018

Если я правильно понял, попробуйте заменить строку elif на следующую:

else:
    longest_UTR = [[locus, mir, gene, transcript, length_as_integer] for x in longest_UTR if x[:3] == [locus, mir, gene] and length_as_integer > int(x[4]) else x]:

Вы просматриваете весь список, обновляя те, которые соответствуют условию, и ничего не делаете, если оно не соответствует.

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