Python 3: Получаване на TypeError: Срезовете трябва да са цели числа, но вярвам, че са

Опитвам се да напиша функция, наречена "средна", която взема средните 3 цифри на нечетни числа или средните 4 цифри на четни числа. Ако числото е по-малко от 5 цифри, то просто връща цялото число. Ето моята работа:

def middle(x):
    mystring=str(x)
    length=len(mystring)
    if len(mystring)<=5:
        return(x)
    elif len(mystring)%2==0:
        return (mystring[((length/2)-1):((length/2)+3)])
    else:
        return (mystring[(length//2):((length//2)+3)])
middle (1234567890)

Продължавам да получавам „грешка при тип: индексите на срезове трябва да са цели числа или никакви или да имат an_index_method“ и не разбирам.


person JackD    schedule 15.10.2012    source източник
comment
Също така възпроизводим на Python 2.7 с from __future__ import division; без това бъдещо изявление работи.   -  person user9876    schedule 15.10.2012


Отговори (2)


Обзалагам се, че използвате Python 3. [И вие сте -- току-що забелязах етикета тази секунда.] length/2 ще бъде плаващ елемент:

    return (mystring[((length/2)-1):((length/2)+3)])

вместо това използвайте length//2 навсякъде.

Обърнете внимание, че това ще се случи дори ако length е четно:

>>> s = 'abcd'
>>> len(s)
4
>>> len(s)/2
2.0
>>> s[len(s)/2:]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: slice indices must be integers or None or have an __index__ method
>>> s[len(s)//2:]
'cd'
person DSM    schedule 15.10.2012
comment
Ами аз използвам единичната наклонена черта само когато цялото число е четно, така че не мисля, че е това. Все пак го пробвах и когато го пуснах, започна да откача (използвам pyscripter)... червеният текст започна да тече в интерпретатора и на всеки няколко реда се казва, че потокът е затворен Еххх... Ще стане не спирай сега - person JackD; 15.10.2012
comment
Звучи сякаш това го поправи и вие открихте следващия бъг :-) - person user9876; 15.10.2012
comment
Излязох от програмата и рестартирах, сега работи добре. Благодаря приятел. (за сега :P) - person JackD; 15.10.2012
comment
+1. 4/2 връща 2.0 в Python 3. / винаги връща float. (Правилото за най-малко изненада се връща отново в този случай за Python 3.) - person pepr; 15.10.2012

Операторът // връща само int, когато числителят е int, докато все пак връща число с плаваща единица, когато числителят е число с плаваща единица.

assert type(2//2) == int
assert type(2.//2) == float

За да се преодолее това ограничение в срезове, може да се използва следната функция:

def intslice(*args, **kwargs):
    '''Return a slice object that has integer boundaries.

    Example:
    np.arange(10)[intslice(10/10,10/2)]
    '''

    args = [int(arg) for arg in args]
    kwargs = {key: int(arg) for key, arg in kwargs.items()}
    return slice(*args, **kwargs)

Сега intslice(10/10,10/2) връща slice(1,5)

person Vasco    schedule 22.03.2018