【问题标题】:Sort the list based on the top level domain (edu, com, org, in)根据顶级域(edu、com、org、in)对列表进行排序
【发布时间】:2019-03-01 04:30:19
【问题描述】:

给定一个列表,

url = ["www.annauniv.edu", "www.google.com", "www.ndtv.com", "www.website.org", "www.bis.org.in", "www.rbi.org.in"];

根据顶级域(edu、com、org、in)对列表进行排序 我对python很陌生,我试图通过按倒数第二个术语排序列表来解决这个问题,即“d,o,r,i”。但是我得到的输出不符合预期你能帮我理解为什么吗?


url = ["www.annauniv.edu", "www.google.com", "www.ndtv.com", "www.website.org", "www.bis.org.in", "www.rbi.org.in"]
def myFn(s):
    return s[-2]

print sorted(url,key=myFn) `

我得到以下输出:

['www.annauniv.edu', 'www.bis.org.in', 'www.rbi.org.in', 'www.google.com', 'www.ndtv.com', 'www.website.org']

但是当我尝试使用此列表url=["x.ax","u.ax","x.cx","y.cx","y.by"] 时,我得到了正确的结果,即

['x.ax', 'u.ax', 'y.by', 'x.cx', 'y.cx']

【问题讨论】:

  • @AshishKumarS 对于url = ["www.annauniv.edu", "www.google.com", "www.ndtv.com", "www.website.org", "www.bis.org.in", "www.rbi.org.in"],预期的输出应该是什么?是否应该按字母顺序排序?
  • @taurus05 他们应该按照这个顺序先 edu 然后 com 然后 org in
  • @AshishKumarS,那我猜这不是字母顺序。
  • @taurus05 如果您在 .edu .com .in .org 中看到 如果您使用 d o i 和 r 排序,那么它可以是字母顺序

标签: python list sorting


【解决方案1】:

更一般地说,您可能还希望“www.google.com”出现在“www.ndtv.com”之前,并且“web3.example.com”出现在“www.example.com”之前,对吧?您可以这样做:

urls = ["www.annauniv.edu", "www.google.com", "www.ndtv.com", "www.website.org", "www.bis.org.in", "www.rbi.org.in"]

def key_function(s):
    # Turn "www.google.com" into ["www", "google", "com"], then
    # reverse it to ["com", "google", "www"].
    return list(reversed(s.split('.')))

# Now this will sort ".com" before ".edu", "google.com" before "ndtv.com",
# and so on.
print(sorted(urls, key=key_function))

【讨论】:

  • s.split('.')[::-1],这可能会更容易一些。无论如何,+1 用于考虑 URL 的其他部分。
  • 根据问题“根据顶级域(edu、com、org、in)对列表进行排序”,所以我需要将 .edu 放在首位 .com 秒等跨度>
  • @KirkStrauser,请参阅问题下方的 cmets。这不是 OP 所期望的。
  • @taurus05 然后我不知道实际期望什么,我放弃了。 :-D
【解决方案2】:

因为你在做-2,所以它会得到倒数第二个字符,所以像com这样结尾的东西只是om,所以使用:

print(sorted(url,key=lambda x: x.split('.')[-1]))

Jab 的版本是使用函数,Kirk 的版本是使用 reversed,但他仍然可以使用 [::-1]

编辑:(感谢 taurus05 纠正我)

def func(x):
    d = {'edu':'e','com':'m','org':'o'}
    return d.get(x.split('.')[-1],'z')

print(sorted(urls, key=func))

【讨论】:

  • @U9-Forward,请参阅问题下方的 cmets。这不是 OP 所期望的。
  • @U9-Forward,您似乎已经习惯了使用 lambda,以至于您忘记了代码的可读性。 :)
【解决方案3】:

s[-2] 表示取右数第二个字符;所以对于“www.annauniv.edu”,这将是“.edu”中的“d”。所以你正在对倒数第二个字符进行排序。

请尝试:

return s.split('.')[-1]

split('.') 会将您的输入字符串(例如,“www.annauniv.edu”)拆分为一个由“.”拆分的列表。字符(即 ["www", "annauniv", "edu"],然后[-1] 将选择右边的第一个字符(即"edu")

编辑:

好的,我看到您想要按特定顺序排序,而不是实际整理。在这种情况下,您需要以某种方式定义该顺序。这是一种方法:

def myFn(s):
    preferred_order = ["edu", "com", "org", "in"]
    tld=s.split('.')[-1]
    return preferred_order.index(tld)

.index() 调用返回字符串在preferred_order 列表中所占的位置(这是一个任意变量名,您可以使用foo 或其他任何名称)。

所以,tld=s.split('.')[-1]tld 设置为“com”或“edu”之类的东西。然后preferred_order.index(tld) 在列表preferred_order 中查找tld 并返回它的位置(从0 开始)。所以对于“edu”,你会得到一个 0;对于“org”,您将得到 2,等等。结果是您将按照您在 preferred_order 中列出它们的顺序进行排序。

如果它达到你没有想到的顶级域名,它会被ValueError 窒息。在这种情况下,您可以使用默认值:

def myFn(s):
    preferred_order = ["edu", "com", "org", "in"]
    tld=s.split('.')[-1]
    try:
        ranking = preferred_order.index(tld)
    except ValueError:
        ranking = 99999 # to sort unknowns at end; use -1 to sort at beginning 
    return ranking

【讨论】:

  • @codingatty,请参阅问题下方的 cmets。这不是 OP 所期望的。
  • @codingatty 你的代码有效,你能告诉我这行“preferred_order.index(tld)”是做什么的吗
  • @AshishKumarS 如果 tld 是 edu,它只返回 0,如果 tld 是 com,则返回 1 等等。
  • 是的,约瑟夫丁说的;我已经对其进行了编辑以使其更加清晰。
【解决方案4】:

没有一个答案,按您的预期工作。这将按预期工作。如需澄清,请阅读问题下方的 cmets。

urls = ["www.annauniv.edu", "www.google.com", "www.ndtv.com", "www.website.org", "www.bis.org.in", "www.rbi.org.in"]

def func(x):
  x = x.split('.')[-1]
  print(x)
  if x == 'edu':
    return 'e'
  elif x == 'com':
    return 'm'
  elif x == 'org':
    return 'o'
  else:
    return 'z'

print(sorted(urls, key=func))

输出:顺序 -> [edu, com, org, in]

['www.annauniv.edu', 'www.google.com', 'www.ndtv.com', 'www.website.org', 'www.bis.org.in', 'www.rbi.org.in']

更新: 我正在返回字母以保持所需的顺序。

【讨论】:

  • 您更改了之前的答案?这将起作用,这很容易理解,谢谢。
  • @AshishKumarS,您可以对其进行投票,以便对其他人也有帮助。
【解决方案5】:

您需要在句点后返回字符串的最后一部分。使用它作为你的函数。

url = ["www.annauniv.edu", "www.google.com", "www.ndtv.com", "www.website.org", "www.bis.org.in", "www.rbi.org.in"]
def myFn(s):
    return s.split('.')[-1]

print sorted(url,key=myFn) 

编辑

由于您的要求比简单的字母数字排序更复杂,因此下面的函数似乎是一个合乎逻辑的解决方案。

def myFunc(s, order=('edu','com','in','org')):
    try: return order.index(s.split('.')[-1])
    except ValueError: return len(order)

【讨论】:

  • @Jab,请参阅问题下方的 cmets。这不是 OP 所期望的。
  • 抱歉,我在工作。我编辑了。感谢您指出这一点
【解决方案6】:

解决此问题的方法是获取整个顶级域,而不仅仅是倒数第二个字符。想象一下,您有两个顶级级别,例如“edu”和“add”。这两个不能保证正确排序,因为“edu”可能在“add”之前结束。所以这里有一个解决方案:

url = ['www.annauniv.edu', 'www.google.com', 'www.ndtv.com', 'www.website.org', 'www.bis.org.in', 'www.rbi.org.in']

def topLevelDomain(domain: str):
    # Split from the right, max of one split.
    # This only takes the right hand side after the last period in the string.
    return domain.rsplit('.', 1)[-1]

print(sorted(url, key=topLevelDomain))

【讨论】:

    【解决方案7】:

    这是因为并非所有 TLD 总是有 2 个字符。随着现在发布的扩展 TLD 越来越多,更长的 TLD 也越来越多。

    您可以使用s.split('.')[-1] 代替s[-2]

    1. 将带有. 的字符串拆分为数组:s.split('.')

      www.bis.org.in
      > ['www', 'bis', 'org', 'in']
      
    2. 获取最后一个元素:[-1]

      > 'in'
      

    最重要的是,您可以指定一个字典,在返回到字母顺序之前先根据该字典排序。

    url = ["www.annauniv.edu", "www.abc.co.uk", "x.dev", "x.mom", "www.google.com", "www.ndtv.com", "www.website.org", "www.bis.org.in", "www.rbi.org.in"]
    
    def myFn(x):
        order = {'edu': 0, 'com': 1, 'org': 2, 'in': 3}
        tld = x.split('.')[-1]
        return order[tld] if tld in order.keys() else tld
    
    print(sorted(url, key=myFn))
    

    会回来

    ['www.annauniv.edu',
     'www.google.com',
     'www.ndtv.com',
     'www.website.org',
     'www.bis.org.in',
     'www.rbi.org.in',
     'x.dev',
     'x.mom',
     'www.abc.co.uk']
    

    幕后发生的事情是数字将排在字符串前面。

    如果 TLD 是 edu、com、org 或 in,则会按照它们各自的编号进行排序。

    其他所有内容都将按照 TLD 本身的字母顺序排序。

    【讨论】:

    • 查看问题下方的 cmets。这不是 OP 所期望的。
    • @taurus05 感谢您的来信。我没有仔细阅读这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-07
    • 2015-01-08
    • 2023-04-01
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多