[英]How to avoid type chaning on last element when removing elements from python lists
編寫程序以返回字符串的所有排列。 試圖將相同的邏輯應用於列表排列。 我在最后一個元素上遇到類型錯誤,因為python將lst的類型更改為不再具有pop方法的字符串。 有辦法避免這種情況嗎?
def permutestring(string, newstr="", array=[]):
if len(string) == 0:
array.append(newstr)
for char in string:
permutestring(string.replace(char, "", 1), newstr + char, array)
return array
print(permutestring("test"))
def permutelist(lst, newlst=[], array=[]):
if not lst:
array.append(newlst)
for item in lst:
permutelist(lst.pop(lst.index(item)), newlst+[item], array)
return array
print(permutelist(["apples", "pears", "oranges", "kiwis"]))
第一個運行良好,並返回所有排列的數組。 第二個嘗試從str對象彈出時拋出AttributeError。
如果您顯式轉換是否可以解決問題?
list(array)
否則,您可以嘗試/捕獲此異常
def permutelist(lst, newlst=[], array=[]):
for item in lst:
try :
permutelist(lst.pop(lst.index(item)), newlst+[item], array)
except AttributeError:
array.append(newlst)
return array
print(permutelist(["apples", "pears", "oranges", "kiwis"]))
這是因為根據[Python 3.Docs]:數據結構 ( 重點是我的)
清單。 彈出 ( [i] )
刪除列表中給定位置的項目, 然后將其返回 。
所以,第1個 彈出將返回將被傳遞到下一個(重復)permutelist通話,這將(顯然)失敗的字符串。
為了解決問題,可以構造一個新列表,而不是lst.pop(lst.index(item))
,該列表包含當前索引之前的元素以及該元素之后的元素(這意味着它將被忽略)。 還要注意使用[Python 3.Docs]:內置函數- 枚舉 ( 可迭代,start = 0 )以避免獲取每個元素的索引。
>>> from pprint import pprint >>> >>> def permutelist(lst, newlst=[], array=[]): ... if not lst: ... array.append(newlst) ... for idx, item in enumerate(lst): ... permutelist(lst[:idx] + lst[idx + 1:], newlst + [item], array) ... return array ... >>> pprint(permutelist(["apples", "pears", "oranges", "kiwis"])) [['apples', 'pears', 'oranges', 'kiwis'], ['apples', 'pears', 'kiwis', 'oranges'], ['apples', 'oranges', 'pears', 'kiwis'], ['apples', 'oranges', 'kiwis', 'pears'], ['apples', 'kiwis', 'pears', 'oranges'], ['apples', 'kiwis', 'oranges', 'pears'], ['pears', 'apples', 'oranges', 'kiwis'], ['pears', 'apples', 'kiwis', 'oranges'], ['pears', 'oranges', 'apples', 'kiwis'], ['pears', 'oranges', 'kiwis', 'apples'], ['pears', 'kiwis', 'apples', 'oranges'], ['pears', 'kiwis', 'oranges', 'apples'], ['oranges', 'apples', 'pears', 'kiwis'], ['oranges', 'apples', 'kiwis', 'pears'], ['oranges', 'pears', 'apples', 'kiwis'], ['oranges', 'pears', 'kiwis', 'apples'], ['oranges', 'kiwis', 'apples', 'pears'], ['oranges', 'kiwis', 'pears', 'apples'], ['kiwis', 'apples', 'pears', 'oranges'], ['kiwis', 'apples', 'oranges', 'pears'], ['kiwis', 'pears', 'apples', 'oranges'], ['kiwis', 'pears', 'oranges', 'apples'], ['kiwis', 'oranges', 'apples', 'pears'], ['kiwis', 'oranges', 'pears', 'apples']]
或者,使用[Python 3.Docs]:itertools 更有意義 。 排列 ( 可迭代,r = None ) ,它執行相同的操作(最有可能,更快,更好)。
>>> pprint(list(itertools.permutations(["apples", "pears", "oranges", "kiwis"]))) [('apples', 'pears', 'oranges', 'kiwis'), ('apples', 'pears', 'kiwis', 'oranges'), ('apples', 'oranges', 'pears', 'kiwis'), ('apples', 'oranges', 'kiwis', 'pears'), ('apples', 'kiwis', 'pears', 'oranges'), ('apples', 'kiwis', 'oranges', 'pears'), ('pears', 'apples', 'oranges', 'kiwis'), ('pears', 'apples', 'kiwis', 'oranges'), ('pears', 'oranges', 'apples', 'kiwis'), ('pears', 'oranges', 'kiwis', 'apples'), ('pears', 'kiwis', 'apples', 'oranges'), ('pears', 'kiwis', 'oranges', 'apples'), ('oranges', 'apples', 'pears', 'kiwis'), ('oranges', 'apples', 'kiwis', 'pears'), ('oranges', 'pears', 'apples', 'kiwis'), ('oranges', 'pears', 'kiwis', 'apples'), ('oranges', 'kiwis', 'apples', 'pears'), ('oranges', 'kiwis', 'pears', 'apples'), ('kiwis', 'apples', 'pears', 'oranges'), ('kiwis', 'apples', 'oranges', 'pears'), ('kiwis', 'pears', 'apples', 'oranges'), ('kiwis', 'pears', 'oranges', 'apples'), ('kiwis', 'oranges', 'apples', 'pears'), ('kiwis', 'oranges', 'pears', 'apples')]
lst.pop()將為其刪除的索引返回給定值。 在您的情況下,這是一個字符串。 為避免這種情況,只需將字符串包裝在新列表的索引處,然后在新列表上調用函數:
def permutelist(lst, newlst=[], array=[]):
print(lst)
print(type(lst))
if not lst:
array.append(newlst)
for item in lst:
new_list = []
new_list.append(new_list.append(lst.pop(lst.index(item))))
permutelist(new_list, newlst+[item], array)
return array
print(permutelist(["apples", "pears", "oranges", "kiwis"]))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.