如何记录对一个字符串使用 sort in python 时发生的事情的历史记录,并将其应用于其他字符串?
How do I record the history of what happened while using sort in python for one string, and apply that to other strings?
with open(sys.argv[1]) as f:
lst = list(f.readline().strip())
sortedLst = sorted(lst, key = lambda x: (x.lower(), x.swapcase()))
print(lst)
print(sortedLst)
我用作示例的单词是 'ThatCcer'。
我的输出是 ['T'、'h'、'a'、't'、'C'、'c'、'e'、'r'] 对于 lst,我的输出是 ['a'、'c'、'C'、'e'、'h'、'r'、't' , 'T'] for sortedLst.
这正是我想要的 - 按字母顺序对单词进行排序,小写字母优先于大写字母。
我想要实现的是通过按照我对 ThatCcher 进行排序的方式对它们进行排序来匹配其他 8 个字母的输入。我将如何实现这一目标?
编辑:我被告知问题不清楚 - 我很抱歉,但解释起来有点困难,所以我会再试一次。
通过排序ThatCcer成为acCehrtT,lst[0]('T')占据了sortedLst[7]的位置,lst[1]('h')占据了sortedLst[4的位置],等等...
这是我要记录的历史,这样给定的任何其他字符串都可以复制 'ThatCcer' 采取的步骤,例如:s = ['h', 'o', 'w', 'e', 'v', 'e', 'r', 's']
我希望 s[0] 采取它的' 在 sortedS[7] 中的位置,就像 ThatCcer 所做的那样。
我希望这能让它更清楚一点!
IIUC,您想实现类似于 numpy.argsort
的行为。
您可以根据您的条件对范围进行排序,并使用它重新索引任何字符串:
lst = ['T', 'h', 'a', 't', 'C', 'c', 'e', 'r']
idx = list(range(len(lst)))
sorted_idx = sorted(idx, key=lambda x: (lst[x].lower(), lst[x].swapcase()))
# [2, 5, 4, 6, 1, 7, 3, 0]
# now use the index to sort
[lst[i] for i in sorted_idx]
# ['a', 'c', 'C', 'e', 'h', 'r', 't', 'T']
# keep the same order on another string
lst2 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
[lst2[i] for i in sorted_idx]
# ['c', 'f', 'e', 'g', 'b', 'h', 'd', 'a']
另一种使用zip
的方法:
lst = ['T', 'h', 'a', 't', 'C', 'c', 'e', 'r']
lst2 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
list(zip(*sorted(zip(lst, lst2), key=lambda x: (x[0].lower(), x[0].swapcase()))))
# or as individual lists
# (lst_sorted, lst2_sorted) = list(zip(*sorted(zip(lst, lst2),
# key=lambda x: # (x[0].lower(), x[0].swapcase()))))
输出:
[('a', 'c', 'C', 'e', 'h', 'r', 't', 'T'),
('c', 'f', 'e', 'g', 'b', 'h', 'd', 'a')]
将枚举字符串按字符串字符排序,然后将(已排序)个索引和字符分开;使用 operator.itemgetter 创建一个可调用对象,您可以 re-use.
import operator
def f(thing):
s_lst = sorted(enumerate(thing),key = lambda x: (x[1].lower(), x[1].swapcase()))
argsort = operator.itemgetter(*[x[0] for x in s_lst])
s_lst = [x[1] for x in s_lst]
return s_lst,argsort
>>> s_lst, argsort = f('ThatCcerCTaa')
>>> s_lst
['a', 'a', 'a', 'c', 'C', 'C', 'e', 'h', 'r', 't', 'T', 'T']
>>> argsort('ThatCcerCTaa')
('a', 'a', 'a', 'c', 'C', 'C', 'e', 'h', 'r', 't', 'T', 'T')
>>> argsort
operator.itemgetter(2, 10, 11, 5, 4, 8, 6, 1, 7, 3, 0, 9)
>>>
with open(sys.argv[1]) as f:
lst = list(f.readline().strip())
sortedLst = sorted(lst, key = lambda x: (x.lower(), x.swapcase()))
print(lst)
print(sortedLst)
我用作示例的单词是 'ThatCcer'。 我的输出是 ['T'、'h'、'a'、't'、'C'、'c'、'e'、'r'] 对于 lst,我的输出是 ['a'、'c'、'C'、'e'、'h'、'r'、't' , 'T'] for sortedLst.
这正是我想要的 - 按字母顺序对单词进行排序,小写字母优先于大写字母。
我想要实现的是通过按照我对 ThatCcher 进行排序的方式对它们进行排序来匹配其他 8 个字母的输入。我将如何实现这一目标?
编辑:我被告知问题不清楚 - 我很抱歉,但解释起来有点困难,所以我会再试一次。
通过排序ThatCcer成为acCehrtT,lst[0]('T')占据了sortedLst[7]的位置,lst[1]('h')占据了sortedLst[4的位置],等等...
这是我要记录的历史,这样给定的任何其他字符串都可以复制 'ThatCcer' 采取的步骤,例如:s = ['h', 'o', 'w', 'e', 'v', 'e', 'r', 's']
我希望 s[0] 采取它的' 在 sortedS[7] 中的位置,就像 ThatCcer 所做的那样。
我希望这能让它更清楚一点!
IIUC,您想实现类似于 numpy.argsort
的行为。
您可以根据您的条件对范围进行排序,并使用它重新索引任何字符串:
lst = ['T', 'h', 'a', 't', 'C', 'c', 'e', 'r']
idx = list(range(len(lst)))
sorted_idx = sorted(idx, key=lambda x: (lst[x].lower(), lst[x].swapcase()))
# [2, 5, 4, 6, 1, 7, 3, 0]
# now use the index to sort
[lst[i] for i in sorted_idx]
# ['a', 'c', 'C', 'e', 'h', 'r', 't', 'T']
# keep the same order on another string
lst2 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
[lst2[i] for i in sorted_idx]
# ['c', 'f', 'e', 'g', 'b', 'h', 'd', 'a']
另一种使用zip
的方法:
lst = ['T', 'h', 'a', 't', 'C', 'c', 'e', 'r']
lst2 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
list(zip(*sorted(zip(lst, lst2), key=lambda x: (x[0].lower(), x[0].swapcase()))))
# or as individual lists
# (lst_sorted, lst2_sorted) = list(zip(*sorted(zip(lst, lst2),
# key=lambda x: # (x[0].lower(), x[0].swapcase()))))
输出:
[('a', 'c', 'C', 'e', 'h', 'r', 't', 'T'),
('c', 'f', 'e', 'g', 'b', 'h', 'd', 'a')]
将枚举字符串按字符串字符排序,然后将(已排序)个索引和字符分开;使用 operator.itemgetter 创建一个可调用对象,您可以 re-use.
import operator
def f(thing):
s_lst = sorted(enumerate(thing),key = lambda x: (x[1].lower(), x[1].swapcase()))
argsort = operator.itemgetter(*[x[0] for x in s_lst])
s_lst = [x[1] for x in s_lst]
return s_lst,argsort
>>> s_lst, argsort = f('ThatCcerCTaa')
>>> s_lst
['a', 'a', 'a', 'c', 'C', 'C', 'e', 'h', 'r', 't', 'T', 'T']
>>> argsort('ThatCcerCTaa')
('a', 'a', 'a', 'c', 'C', 'C', 'e', 'h', 'r', 't', 'T', 'T')
>>> argsort
operator.itemgetter(2, 10, 11, 5, 4, 8, 6, 1, 7, 3, 0, 9)
>>>