#python #arrays #csv #cs50
#python #массивы #csv #cs50
Вопрос:
Моя проблема: я пытаюсь сравнить два элемента из двух разных массивов, но оператор не работает.
Рассматриваемый фрагмент кода:
for i in range(row_length):
print(f"ss_record: {ss_record[i]}")
print(f"row: {row[i 1]}")
#THIS IF STATEMENT IS NOT WORKING
if ss_record[i] == row[i 1]:
count = 1
#print()
#print(f"row length: {row_length}")
#print(f"count: {count}")
if count == row_length:
print(row[0])
exit(0)
Что я сделал: я попытался напечатать значение ss_record
и row
до того, как оно пройдет через if
инструкцию, но когда оно совпадает, count
не увеличивается. Я попытался сохранить значение row
в новом массиве, но он выдает ошибку и сохраняет только длину массива и первые 2 значения строки и повторяет эти значения в каждом следующем экземпляре.
Что я думаю о проблеме: я думаю, что проблема с моим кодом заключается в том, что строка считывается из CSV
файла и в результате не преобразуется в целое число, кажется, что они одинаковы, но одна является целым числом, а другая — строкой.
Весь Код целиком:
import csv
import sys
import re
from cs50 import get_string
from sys import argv
def main():
line_count = 0
if len(argv) != 3:
print("missing command-line argument")
exit(1)
with open(sys.argv[1], 'r') as database:
sequence = open(sys.argv[2], 'r')
string = sequence.read()
reader = csv.reader(database, delimiter = ',')
for row in reader:
if line_count == 0:
row_length = len(row) - 1
ss_record = [row_length]
for i in range(row_length):
ss_record.append(ss_count(string, row[i 1], len(row[i 1])))
ss_record.pop(0)
line_count = 1
else:
count = 0
for i in range(row_length):
print(f"ss_record: {ss_record[i]}")
print(f"row: {row[i 1]}")
#THIS IF STATEMENT IS NOT WORKING
if ss_record[i] == row[i 1]:
count = 1
if count == row_length:
print(row[0])
exit(0)
#ss_count mean the # of times the substring appear in the string
def ss_count(string, substring, length):
count = 1
record = 0
pos_array = []
for m in re.finditer(substring, string):
pos_array.append(m.start())
for i in range(len(pos_array) - 1):
if pos_array[i 1] - pos_array[i] == length:
count = 1
else:
if count > record:
record = count
count = 1
if count > record:
record = count
return record
main()
Значения, используемые для воспроизведения проблемы:
последовательность (это текстовый файл) = AAGGTAAGTTTAGAATATAAAAGGTGAGTTAAATAGAATAGGTTAAAATTAAAGGAGATCAGATCAGATCAGATCTATCTATCTATCTATCTATCAGAAAAGAGTAAATAGTTAAAGAGTAAGATATTGAATTAATGGAAAATATTGTTGGGGAAAGGAGGGATAGAAGG
подстрока (это файл CSV) =
имя, AGATC, AATG, TATC
Алиса, 2,8,3
Боб, 4,1,5
Чарли, 3,2,5
Суть файла CSV: Цифры рядом с Алисой означают, сколько раз подстрока (STR / короткий тандемный повтор) появляется в строке в строке (последовательности ДНК). В этой строке AGATC появляется 4 раза подряд, AATG появляется 1 раз подряд, а TATC появляется 5 раз подряд. Для этой последовательности ДНК она соответствует Bob, и он выводится в качестве ответа.
Ответ №1:
Вы были правы, при сравнении ss_record[i] == row[i 1]:
возникает проблема с типом, номера ss_record являются целыми числами, а номера строки — строками. Вы можете подтвердить проблему, напечатав оба ss_record
и row
:
print("ss_record: {}".format(ss_record)) -> ss_record: [4, 1, 5]
print("row: {}".format(row)) -> row: ['Alice', '2', '8', '3']
Для того, чтобы фрагмент работал, вам просто нужно изменить сравнение на
ss_record[i] == int(row[i 1])
Тем не менее, я чувствую, что код довольно сложный для этой задачи. Класс string реализует count
метод, который возвращает количество неперекрывающихся вхождений данной подстроки. Кроме того, поскольку код, с которым он работает, основан на элементах и сильно зависит от манипуляций с индексом, логику итерации сложно отслеживать (IMO). Вот мой подход к проблеме:
import csv
def match_user(dna_file, user_csv):
with open(dna_file, 'r') as r:
dna_seq = r.readline()
with open(user_csv, 'r') as r:
reader = csv.reader(r)
rows = list(reader)
target_substrings = rows[0][1:]
users = rows[1:]
num_matches = [dna_seq.count(target) for target in target_substrings]
for user in users:
user_matches = [int(x) for x in user[1:]]
if user_matches == num_matches:
return user[0]
return "Not found"
Счастливого кодирования!
Комментарии:
1. Я не понимаю, как работает эта логика:
[dna_seq.count(target) for target in target_substrings]
. Я понимаю, что это pythonic, но как это работает.2. @manav-dubey Этот синтаксис называется пониманием списка . По сути, это способ смешивания итерации и вычисления, слегка напоминающий математическую нотацию для построения множеств . Перевод на английский был бы:
For every STR check in the dna sequence how many times it appears and save these results into a list