简体   繁体   English

根据它们所属的类别集重新排列字符串中的单词

[英]Rearrange words in a string based on which category set they belong to

How would I rearrange a string based on what category it belongs to?如何根据字符串所属的类别重新排列字符串? Let's say I have these sets:假设我有这些套装:

dogs = {'husky', 'chihuahua', 'labrador', 'beagle'} 
flowers = {'dandelion', 'rose', 'tulip'} 
colours = {'blue', 'yellow', 'green', 'red', 'pink'}

Then let's say I wanted to input a string and rearrange the words based on their category.然后假设我想输入一个字符串并根据它们的类别重新排列单词。

'husky tulip red orange'

would become会成为

'red orange husky tulip'

The order would be colours first, then dogs, then flowers.顺序是先是颜色,然后是狗,然后是花。 Maybe create a list of the categories in order?也许按顺序创建一个类别列表? Not too sure how I would go about this不太确定我会怎么做

Use a key function with sorted :使用带有sorted的键函数:

def ref(s):
    dogs = {'husky', 'chihuahua', 'labrador', 'beagle'} 
    flowers = {'dandelion', 'rose', 'tulip'} 
    colours = {'blue', 'yellow', 'green', 'red', 'pink', 'orange'}
    if s in colours: rtr=-3
    elif s in dogs: rtr=-2
    elif s in flowers: rtr=-1
    else: rtr=0   # this puts words not found at end of string
    return rtr 

s='husky tulip red orange'

>>> ' '.join(sorted(s.split(), key=ref))
red orange husky tulip

More Pythony (and easier to extend) is to do something like this:更多的Pythony (并且更容易扩展)是做这样的事情:

def ref(s):
    dogs = {'husky', 'chihuahua', 'labrador', 'beagle'} 
    flowers = {'dandelion', 'rose', 'tulip'} 
    colours = {'blue', 'yellow', 'green', 'red', 'pink', 'orange'}
    key_t=(colours, dogs, flowers)
    try: 
        return next(i for i, v in enumerate(key_t) if s in v)
    except StopIteration:
        return -1. # this puts words not found at beginning of string
    # or use the default argument version of next:
    # return next((i for i, v in enumerate(key_t) if s in v), -1)

And use that key function the same way.并以相同的方式使用该键功能。

You can also iterate the sets by using chain to chain the sets together into a single iterable:您也可以通过使用迭代套来链集合在一起成为一个单一的迭代:

>>> from itertools import chain
>>> [e for e in chain(colours,dogs,flowers) if e in s.split()]
['orange', 'red', 'husky', 'tulip']

Which is faster or better depends on the size of the string and the size of the sets.哪个更快或更好取决于字符串的大小和集合的大小。 Also if you wanted to do secondary sorts (such as lexicographic within the individual categories) you need to use the sorted method.此外,如果您想进行二级排序(例如各个类别中的字典sorted ),则需要使用sorted方法。

Try this尝试这个

#Define all the categories
dogs = ['husky', 'chihuahua', 'labrador', 'beagle']
flowers = ['dandelion', 'rose', 'tulip']
colours = ['blue', 'yellow', 'green', 'red', 'pink', 'orange']

#The Input String
outOfOrder = "husky tulip red orange"

#Split up the string into an array which each word seperated
outOfOrderArray = outOfOrder.split()

#Array to hold all words of each category
orderedArray = [[], [], [], []]

#loop through all the words in the array
for word in outOfOrderArray:

    #Check if the word is in each category.
    if word in dogs:
        orderedArray[2].append(word)
    elif word in flowers:
        orderedArray[1].append(word)
    elif word in colours:
        orderedArray[0].append(word)

    #If its not in the array, do whatever you want with it. I jsut stuck them at the end.
    else:
        orderedArray[3].append(word)

orderedString = ""

#Combine all the words in ordered Array to create a final string
for category in orderedArray:
    for word in category:
        orderedString = orderedString + word + " "

print(orderedString)

You could push flowers to the back with key 1 and pull colours to the front with key -1 (and everything else will go in the middle with key 0 ):你可能会推动花卉与键后1和拉的颜色前用钥匙-1 (一切将与主要的中间去0 ):

>>> ' '.join(sorted(s.split(), key=lambda w: (w in flowers) - (w in colours)))
'red husky orange tulip'

Note that "orange" isn't in any of your categories, which is why it ended up in the middle along with "husky".请注意,“橙色”不属于您的任何类别,这就是为什么它与“哈士奇”一起出现在中间的原因。

A more general way pushes flowers furthest back, dogs less back, and colours least back:一种更通用的方法是将花朵向后推得最远,狗向后推得更少,颜色向后推得最少:

>>> ' '.join(sorted(s.split(), key=lambda w: (w in flowers, w in dogs, w in colours)))
'orange red husky tulip'

Simply pluck out the matching strings from collection in order:只需按顺序从集合中提取匹配的字符串:

>>>[i for i in list(colours)+list(flowers)+list(dogs) if i in input_list]
['red', 'orange', 'tulip', 'husky']

No need to perform sorting or anything.无需执行排序或任何操作。

Even simpler if you originally define them as lists instead of sets.如果您最初将它们定义为列表而不是集合,则更简单。 Plus it will retain the order you will put in the lists instead of doing a collective sorting of all items:此外,它将保留您将放入列表的顺序,而不是对所有项目进行集体排序:

dogs = ['husky', 'chihuahua', 'labrador', 'beagle']
flowers = ['dandelion', 'rose', 'tulip'] 
colours = ['blue', 'yellow', 'green', 'red', 'pink', 'orange']

input_list = 'husky tulip red orange pink blue'.split()

[i for i in colours+flowers+dogs if i in input_list]

outputs in:输出:

['blue', 'red', 'pink', 'orange', 'tulip', 'husky'] # note the ordering

PS Seems most pythonic, most time-space efficient, most scalable and the fastest approach to me. PS 对我来说似乎是最pythonic、最高效、最可扩展和最快的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM