簡體   English   中英

Java 中的 TreeSet 等效於 Python 嗎?

[英]Java's TreeSet equivalent in Python?

我最近遇到了一些 Java 代碼,它只是將一些字符串放入 Java TreeSet,為它實現了一個基於距離的比較器,然后在日落時分快樂地計算給定的分數來解決給定的問題。

我的問題,

  • 是否有可用於 Python 的等效數據結構?

    • Java 樹集看起來基本上是一個有序字典,它可以使用某種比較器來實現這種排序。
  • 我看到有一個用於OrderedDict 的Py3K PEP ,但我使用的是 2.6.x。 那里有一堆有序的 dict 實現 - 特別是有人可以推薦嗎?

PS,只是補充一下 - 我可能會導入 DictMixin 或 UserDict 並實現我自己的排序/有序字典,並通過比較器功能實現它 - 但這似乎有點矯枉過正。

謝謝。


更新。 感謝您的回答。 詳細說明一下,假設我有一個比較函數,其定義如下(給定特定值 ln),

def mycmp(x1, y1, ln):
  a = abs(x1-ln)
  b = abs(y1-ln)
  if a<b:
    return -1
  elif a>b:
    return 1
  else:
    return 0

我有點不確定如何將其集成到此處給出的有序 dict 鏈接中給出的排序中..

就像是,

OrderedDict(sorted(d.items(), cmp=mycmp(len)))

歡迎提出想法。

collections.OrderedDict的 Python 2.7 文檔有一個指向在 Python 2.4 或更高版本上運行的OrderedDict 配方的鏈接。

編輯:關於排序:使用key=而不是cmp= 它往往會導致更快的代碼,而且, cmp=關鍵字已在 Python3 中消除。

d={5:6,7:8,100:101,1:2,3:4}
print(d.items())
# [(1, 2), (3, 4), (100, 101), (5, 6), (7, 8)]

您為mycmp發布的代碼沒有說明您想要作為x1傳遞的內容。 下面,我假定X1應該是在每個鍵-值對的 如果是這樣,你可以這樣做:

length=4
print(sorted(d.items(),key=lambda item: abs(item[1]-length) ))
# [(3, 4), (1, 2), (5, 6), (7, 8), (100, 101)]

key=...傳遞了一個函數, lambda item: abs(item[1]-length) 對於d.items()每個item ,lambda 函數返回數字abs(item[1]-length) 就排序而言,此數字充當項目的代理。 有關在 Python 中對習語進行排序的更多信息,請參閱這篇文章

附注。 len是一個 Python 內置函數。 為了不破壞len ,我已將變量名稱更改為length

我最近使用 bisect 模塊為 Python 實現了 TreeSet。

https://github.com/fukatani/TreeSet

它的用法類似於 Java 的 Treeset。

前任。

from treeset import TreeSet
ts = TreeSet([3,7,2,7,1,3])
print(ts)
>>> [1, 2, 3, 7]

ts.add(4)
print(ts)
>>> [1, 2, 3, 4, 7]

ts.remove(7)
print(ts)
>>> [1, 2, 3, 4]

print(ts[2])
>>> 3

我需要查看一些示例數據,但如果您只是嘗試進行加權排序,那么內置的 python sorted() 可以通過兩種方式完成。

使用有序元組和 key() 函數:

def cost_per_page(book):
    title, pagecount, cost = book
    return float(cost)/pagecount

booklist = [
        ("Grey's Anatomy", 3000, 200),
        ('The Hobbit', 300, 7.25),
        ('Moby Dick', 4000, 4.75),
]
for book in sorted(booklist, key=cost_per_page):
    print book

或者使用帶有__cmp__運算符的類。

class Book(object):
    def __init__(self, title, pagecount, cost):
        self.title = title
        self.pagecount = pagecount
        self.cost = cost
    def pagecost(self):
        return float(self.cost)/self.pagecount
    def __cmp__(self, other):
        'only comparable with other books'
        return cmp(self.pagecost(), other.pagecost())
    def __str__(self):
        return str((self.title, self.pagecount, self.cost))

booklist = [
        Book("Grey's Anatomy", 3000, 200),
        Book('The Hobbit', 300, 7.25),
        Book('Moby Dick', 4000, 4.75),
]
for book in sorted(booklist):
    print book

這兩個都返回相同的輸出:

('Moby Dick', 4000, 4.75)
('The Hobbit', 300, 7.25)
("Grey's Anatomy", 3000, 200)

1.我認為python沒有內置的排序集。 這樣的事情怎么樣?

letters = ['w', 'Z', 'Q', 'B', 'C', 'A']
  for l in sorted(set(letters)):
     print l

2.Java TreeSet是一個名為SortedSet的抽象的實現。 基本類型會自然order.A進行排序TreeSet情況下使用它的對所有鍵進行比較(或比較)method.So您的自定義鍵應該實施適當compareTo

如果你想要的是一個總是按排序順序迭代的集合,這可能會讓你獲得大部分方法:

def invalidate_sorted(f):
    def wrapper(self, *args, **kwargs):
        self._sort_cache = None
        return f(self, *args, **kwargs)
    return wrapper

class SortedSet(set):
    _sort_cache = None

    _invalidate_sort_methods = """
        add clear difference_update discard intersection_update
        symmetric_difference_update pop remove update
        __iand__ __ior__ __isub__ __ixor__
        """.split()

    def __iter__(self):
        if not self._sort_cache:
            self._sort_cache = sorted(set.__iter__(self))
        for item in self._sort_cache:
            yield item

    def __repr__(self):
        return '%s(%r)' % (type(self).__name__, list(self))

    for methodname in _invalidate_sort_methods:
        locals()[methodname] = invalidate_sorted(getattr(set, methodname))

當您使用 Java 樹集時:

 import java.util.*;
class Main{
         public static void main(String args[])
          {
             TreeSet<Integer> tr=new TreeSet<>();
             tr.add(3);
             tr.add(5);
             tr.add(7);
             tr.add(6);
             tr.add(3);
             tr.add(8);

             Iterator itr=tr.iterator();
             for(int i=0;i<tr.size();i++)
            {
               System.out.print(tr.get(i)+" ");  
            } 
          }
     }

    >>>> **3 5 6 7 8**


  same AS in python:
from treeset import TreeSet
tr = TreeSet([1,2,2,7,4,3])
print(tr)
>>> [1, 2, 3, 4,7] 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM