2013-07-17 3 views
0

Я - опытный Java-программист, который повторно реализует некоторый код в Python, так как я просто изучаю язык. Проблема, которую я испытываю, заключается в том, что метод не возвращает ничего, когда я передаю глобальные переменные, но возвращающ предназначенный код, когда литералы передаются. Код возвращает список слов указанной длины, прошедших в, начиная с переданной строки в Например:.Передача в глобальных переменных в Python

print getNGramBeginsWords("ha", 5) 

возвращается

['HAAFS', 'HAARS', 'HABIT', 'HABUS', 'HACEK', 'HACKS', 'HADAL', 'HADED', 'HADES', 
'HADJI', 'HADST', 'HAEMS', 'HAETS', 'HAFIZ', 'HAFTS', 'HAHAS', 'HAIKA', 'HAIKS', 
'HAIKU', 'HAILS', 'HAINT', 'HAIRS', 'HAIRY', 'HAJES', 'HAJIS', 'HAJJI', 'HAKES', 
'HAKIM', 'HAKUS', 'HALAL', 'HALED', 'HALER', 'HALES', 'HALID', 'HALLO', 'HALLS', 
'HALMA','HALMS', 'HALON', 'HALOS', 'HALTS', 'HALVA', 'HALVE', 'HAMAL', 'HAMES', 
'HAMMY', 'HAMZA', 'HANCE', 'HANDS', 'HANDY', 'HANGS', 'HANKS', 'HANKY', 'HANSA', 
'HANSE', 'HANTS', 'HAOLE', 'HAPAX', 'HAPLY', 'HAPPY', 'HARDS', 'HARDY', 'HARED', 
'HAREM', 'HARES', 'HARKS', 'HARLS', 'HARMS', 'HARPS', 'HARPY', 'HARRY', 'HARSH', 
'HARTS', 'HASPS', 'HASTE', 'HASTY', 'HATCH', 'HATED', 'HATER', 'HATES', 'HAUGH', 
'HAULM', 'HAULS', 'HAUNT', 'HAUTE', 'HAVEN', 'HAVER', 'HAVES', 'HAVOC', 'HAWED', 
'HAWKS', 'HAWSE', 'HAYED', 'HAYER', 'HAYEY', 'HAZAN', 'HAZED', 'HAZEL', 'HAZER', 
'HAZES'] 

, как это должно быть. Однако

print inputString 
print numLetters 
print getNGramBeginsWords(inputString, numLetters) 

возвращает

ha 
5 
[] 

inputString и numLetters глобальные переменные, которые я видел, называется «опасным», хотя я не знаю, почему, и думал, что они могут быть причиной этой странности? Даже локальные копии глобальных переменных, используемых в качестве параметров, не помогают. Возможно, мне нужно использовать «глобальное» ключевое слово в параметрах метода, хотя из моих исследований кажется, что вам не нужно «глобальное» ключевое слово, если вы не изменяете глобальную переменную? Любое предложение или помощь будут оценены. На авось, что это проблема с методом, здесь:

def getNGramBeginsWords(nGram, length): 
    dict = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r') 
    nGram = nGram.upper() 
    words = [] 
    for line in dict: 
     if(len(line)>0): 
      if(len(nGram)>len(line.strip()) | len(line.strip())!= length): 
       continue 
      s = line.strip()[:len(nGram)] 
      if(s == nGram and len(line.strip()) == length): 
       words.append(line.strip()) 
    return words 
+2

Если вы: 'тип печати (numLetters)' перед вызовом 'getNGramBeginsWords', вы получите' 'или' '? Я подозреваю, что вы получили последнее, так что для каждой строки вы сравниваете длину строки с строкой '' 5 "'. (Side note: 'dict' - это имя типа в Python. Вы можете повторно использовать их в качестве локальных переменных, это просто делает сюрприз, когда вы затем пытаетесь сделать dict, вызывая' dict'. Возможно, используйте 'stream 'вместо имени переменной :-)) – torek

+1

Вы уверены, что это' '' вы хотите в 'if (len (nGram)> len (line.strip()) | len (line.strip())! = длина) '. Потому что в Python '|' побитовое ИЛИ и 'or' является логическим ИЛИ. –

+0

Кроме того, не забудьте закрыть файл 'dict'. Попробуйте использовать 'with open (..., 'r') в качестве dict:' statement. –

ответ

1

ТЛ; др: глобальные переменные не имеют ничего сделать с этим; почти наверняка вы передаете строку вместо int в качестве параметра длины. У вашего кода было много увольнений.

Ваш код имеет ряд очевидных проблем, как стилистические и предметный:

def getNGramBeginsWords(nGram, length): 
    # dict is the name of a builtin function, which you are confusingly overwriting 
    # dict = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r') 
    wlist = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r') 
    nGram = nGram.upper() 
    words = [] 
    for line in wlist: 
     # an empty string evaluates to False in a binary context; also no need for those brackets 
     stripline = line.strip().upper() # you keep doing this; I added the upper here. 
     # you don't need this if, because you immediately test length 
     #if stripline: #I know I changed this, but you only refer to the stripped version below 
     # pipe | is bitwise OR. I bet you don't want that 
     if len(nGram)>len(stripline) or len(stripline)!= length: 
      continue 
     # s = stripline[:len(nGram)] #you only use this once 
     # you don't need to check that stripline is of length again; you already did that 
     # also, you can just use `endswith` instead of slicing 
     if stripline.endswith(nGram): 
      words.append(stripline) 
    return words 

И, без комментариев:

def getNGramBeginsWords(nGram, length): 
    wlist = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r') 
    nGram = nGram.upper() 
    words = [] 
    for line in wlist: 
     stripline = line.strip() # you keep doing this 
     # you can merge these two ifs 
     if len(nGram)>len(stripline) or len(stripline)!= length: 
      continue 
     if stripline.endswith(nGram): 
      words.append(stripline) 
    return words 

Слияние двух смежных IFS:

def getNGramBeginsWords(nGram, length): 
    wlist = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r') 
    nGram = nGram.upper() 
    words = [] 
    for line in wlist: 
     stripline = line.strip().upper() # you keep doing this 
     # you can merge these two ifs 
     # also this renders the comparison of ngram and stripline lengths redundant 
     if (len(stripline) == length) and stripline.endswith(nGram): 
      words.append(stripline) 
    return words 

Теперь давайте посмотрим на эту последнюю версию - достаточно забавно, вы никогда не выполняете числовую операцию n на length. Учитывая, что длина должна быть числом, вы можете заставить ее указать число; если он не может быть преобразован, вы получите исключение.

def getNGramBeginsWords(nGram, length): 
    wlist = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r') 
    nGram = nGram.upper() 
    words = [] 
    length = int(length) # force to an int 
    assert isinstance(n, int) # or do this if you prefer to get an exception on all invalid input 
    for line in wlist: 
     stripline = line.strip().upper() # you keep doing this 
     # you can merge these two ifs 
     if (len(stripline) == length) and stripline.endswith(nGram): 
      words.append(stripline) 
    return words 

И, наконец, вы никогда не закрываете файл явно. У тебя будет какое-то время. Это лучше использовать with конструкцию, чтобы закрыть его автоматически:

def getNGramBeginsWords(nGram, length): 
    with open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r') as wlist: 
     nGram = nGram.upper() 
     words = [] 
     length = int(length) # force to an int 
     assert isinstance(n, int) # or do this if you prefer to get an exception on all invalid input 
     for line in wlist: 
      stripline = line.strip().upper() # you keep doing this 
      #you should be using `endswith` instead of the slice 
      if (len(stripline) == length) and stripline.endswith(nGram): 
       words.append(stripline) 
     return words 
+0

Спасибо, я выполнил большинство изменений, которые вы рекомендовали, помимо «stripline.endsWith (nGram)), скорее, я хотел, чтобы он начинался с. Проблема заключалась в том, что я« добавлял »значения в numLetters с« raw_input() », без кастинга до целого числа, я слишком привык к Scanner.nextInt() из java. Извините за все глупые ошибки и спасибо за то, что помогли мне исправить их! – Thatsillogical

+0

@Thatsillogical Добро пожаловать. Если этот ответ помог вам большинство, не стесняйтесь принять его. – Marcin