Python - создание счетчиков, создание циклов? - PullRequest
2 голосов
/ 04 июня 2010

У меня возникли проблемы с кодом ниже:

Ввод: li - это вложенный список, как показано ниже:

li = [['>0123456789 mouse gene 1\n', 'ATGTTGGGTT/CTTAGTTG\n', 'ATGGGGTTCCT/A\n'],   ['>9876543210 mouse gene 2\n', 'ATTTGGTTTCCT\n', 'ATTCAATTTTAAGGGGGGGG\n']]

Используя нижеприведенную функцию, мой желаемый результат - просто от 2-й до 9-й цифры после '>' при условии, что число '/', присутствующее во всем подсписке, составляет> 1.

Вместо этого мой код дает цифры для всех записей. Кроме того, это дает им несколько раз. Поэтому я предполагаю, что что-то не так с моим счетчиком и циклом for. Я не могу понять это.

Любая помощь, высоко ценится.

import os

cwd = os.getcwd()


def func_one():
    outp = open('something.txt', 'w')       #output file
    li = []
    for i in os.listdir(cwd):           
        if i.endswith('.ext'):
            inp = open(i, 'r').readlines()
            li.append(inp)
    count = 0
    lis = []
    for i in li:
        for j in i:
            for k in j[1:]          #ignore first entry in sublist
                if k == '/':
                    count += 1
                if count > 1:
                    lis.append(i[0][1:10])      
                    next_func(lis, outp)

Спасибо, S: -)

Ответы [ 3 ]

9 голосов
/ 04 июня 2010

Возможно, ваш отступ неправильный, вы должны проверить count > 1 в цикле for j in i, а не в том, который проверяет каждый отдельный символ в j[1:].

Кроме того, вот гораздо более простой способ сделать то же самое:

def count_slashes(items):
    return sum(item.count('/') for item in items)

for item in li:
    if count_slashes(item[1:]) > 1:
        print item[0][1:10]

Или, если вам нужны идентификаторы в списке:

result = [item[0][1:10] for item in li if count_slashes(item[1:]) > 1]

Python списочные выражения и выражения генератора - действительно мощные инструменты, попробуйте научиться их использовать, поскольку это значительно упрощает вашу жизнь. Вышеприведенная функция count_slashes использует выражение генератора, а в моем последнем фрагменте кода используется понимание списка, чтобы создать список результатов в хорошем и кратком виде.

8 голосов
/ 04 июня 2010

Тамас предложил хорошее решение, хотя он использует совсем другой стиль кодирования, чем вы.Тем не менее, поскольку ваш вопрос был «У меня возникли проблемы с фрагментом кода ниже», я думаю, что нужно что-то еще.

Как избежать этих проблем в будущем

Вы допустили несколько ошибок в своем подходе к переходу от «я думаю, что я знаю, как написать этот код» к фактическому рабочему коду.

Вы используете бессмысленные имена для своих переменных, что делает егоПрактически невозможно понять ваш код, в том числе и для себя.Мысль «но я знаю, что означает каждая переменная», очевидно, ошибочна, иначе вам удалось бы решить это самостоятельно.Обратите внимание ниже, где я исправляю ваш код, как трудно описать и обсудить ваш код.

Вы пытаетесь решить всю проблему сразу, а не разбивать ее на части.Напишите небольшие функции или фрагменты кода, которые выполняют только одно, по одному фрагменту за раз.Для каждой части, над которой вы работаете, сделайте это правильно и протестируйте, чтобы убедиться, что это правильно.Тогда продолжайте писать другие части, которые, возможно, используют части, которые у вас уже есть.Я говорю «кусочки», но обычно это означает функции, методы или классы.

Исправление вашего кода

Это то, что вы просили, и никто больше этого не делал.

Вам необходимо переместить строку count = 0 после строки for i in li: (с соответствующим отступом).Это сбросит счетчик для каждого подсписка.Во-вторых, после того, как вы добавили lis и запустили next_func, вам нужно выйти из цикла for k in j[1:] и охватывающего цикла for j in i:.

Вот пример рабочего кода (безnext_func, но вы можете добавить это рядом с дополнением):

>>> li = [['>0123456789 mouse gene 1\n', 'ATGTTGGGTT/CTTAGTTG\n', 'ATGGGGTTCCT/A\n'],   ['>9876543210 mouse gene 2\n', 'ATTTGGTTTCCT\n', 'ATTCAATTTTAAGGGGGGGG\n']]
>>> lis = []
>>> for i in li:
        count = 0
        for j in i:
            break_out = False
            for k in j[1:]:
                if k == '/':
                    count += 1
                if count > 1:
                    lis.append(i[0][1:10])
                    break_out = True
                    break
            if break_out:
                break

>>> lis
['012345678']

Переписать ваш код, чтобы сделать его читабельным

Это так, чтобы вы поняли, что я имел в видув начале моего ответа.

>>> def count_slashes(gene):
    "count the number of '/' character in the DNA sequences of the gene."
    count = 0
    dna_sequences = gene[1:]
    for sequence in dna_sequences:
        count += sequence.count('/')
    return count
>>> def get_gene_name(gene):
    "get the name of the gene"
    gene_title_line = gene[0]
    gene_name = gene_title_line[1:10]
    return gene_name
>>> genes = [['>0123456789 mouse gene 1\n', 'ATGTTGGGTT/CTTAGTTG\n', 'ATGGGGTTCCT/A\n'],   ['>9876543210 mouse gene 2\n', 'ATTTGGTTTCCT\n', 'ATTCAATTTTAAGGGGGGGG\n']]
>>> results = []
>>> for gene in genes:
        if count_slashes(gene) > 1:
            results.append(get_gene_name(gene))

>>> results
['012345678']
>>> 
0 голосов
/ 04 июня 2010
import itertools
import glob

lis = []
with open('output.txt', 'w') as outfile:
    for file in glob.iglob('*.ext'):
        content = open(file).read()
        if content.partition('\n')[2].count('/') > 1:
            lis.append(content[1:10])
            next_func(lis, outfile)

Причина, по которой вы вводите цифры для всех записей, заключается в том, что вы не сбрасываете счетчик.

...