简体   繁体   English

Java 中的 TreeSet 等效于 Python 吗?

[英]Java's TreeSet equivalent in Python?

I recently came across some Java code that simply put some strings into a Java TreeSet, implemented a distance based comparator for it, and then made its merry way into the sunset to compute a given score to solve the given problem.我最近遇到了一些 Java 代码,它只是将一些字符串放入 Java TreeSet,为它实现了一个基于距离的比较器,然后在日落时分快乐地计算给定的分数来解决给定的问题。

My questions,我的问题,

  • Is there an equivalent data structure available for Python?是否有可用于 Python 的等效数据结构?

    • The Java treeset looks basically to be an ordered dictionary that can use a comparator of some sort to achieve this ordering. Java 树集看起来基本上是一个有序字典,它可以使用某种比较器来实现这种排序。
  • I see there's a PEP for Py3K for an OrderedDict, but I'm using 2.6.x.我看到有一个用于OrderedDict 的Py3K PEP ,但我使用的是 2.6.x。 There are a bunch of ordered dict implementations out there - anyone in particular that can be recommended?那里有一堆有序的 dict 实现 - 特别是有人可以推荐吗?

PS, Just to add - I could probably import DictMixin or UserDict and implement my own sorted/ordered dictionary, AND make it happen through a comparator function - but that seems to be overkill. PS,只是补充一下 - 我可能会导入 DictMixin 或 UserDict 并实现我自己的排序/有序字典,并通过比较器功能实现它 - 但这似乎有点矫枉过正。

Thanks.谢谢。


Update.更新。 Thanks for the answers.感谢您的回答。 To elaborate a bit, lets say I've got a compare function thats defined like, (given a particular value ln),详细说明一下,假设我有一个比较函数,其定义如下(给定特定值 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

I'm a bit unsure about how I'd integrate this into the ordering given in the ordered dict link given here.. .我有点不确定如何将其集成到此处给出的有序 dict 链接中给出的排序中..

Something like,就像是,

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

Ideas would be welcome.欢迎提出想法。

The Python 2.7 docs for collections.OrderedDict has a link to a OrderedDict recipe that runs on Python 2.4 or better. collections.OrderedDict的 Python 2.7 文档有一个指向在 Python 2.4 或更高版本上运行的OrderedDict 配方的链接。

Edit: In regard to sorting: Use key= rather than cmp= .编辑:关于排序:使用key=而不是cmp= It tends to lead to faster code and moreover, the cmp= keyword has been eliminated in Python3.它往往会导致更快的代码,而且, 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)]

The code you posted for mycmp doesn't make it clear what you want passed as x1 .您为mycmp发布的代码没有说明您想要作为x1传递的内容。 Below, I assume x1 is supposed to be the value in each key-value pair.下面,我假定X1应该是在每个键-值对的 If so, you could do something like this:如果是这样,你可以这样做:

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

key=... is passed a function, lambda item: abs(item[1]-length) . key=...传递了一个函数, lambda item: abs(item[1]-length) For each item in d.items() , the lambda function returns the number abs(item[1]-length) .对于d.items()每个item ,lambda 函数返回数字abs(item[1]-length) This number acts as proxy for the item as far as sorting is concerned.就排序而言,此数字充当项目的代理。 See this essay for more information on sorting idioms in Python.有关在 Python 中对习语进行排序的更多信息,请参阅这篇文章

PS.附注。 len is a Python builtin function. len是一个 Python 内置函数。 So as to not clobber that len , I've changed the variable name to length .为了不破坏len ,我已将变量名称更改为length

I recently implemented TreeSet for Python using bisect module.我最近使用 bisect 模块为 Python 实现了 TreeSet。

https://github.com/fukatani/TreeSet https://github.com/fukatani/TreeSet

Its usage is similar to Java's Treeset.它的用法类似于 Java 的 Treeset。

ex.前任。

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

I'd need to see some example data, but if you're just trying to do a weighted sort, then the builtin python sorted() can do it, two ways.我需要查看一些示例数据,但如果您只是尝试进行加权排序,那么内置的 python sorted() 可以通过两种方式完成。

With well ordered tuples and a key() function:使用有序元组和 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

or with a class with a __cmp__ operator.或者使用带有__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

Both of these return the same output:这两个都返回相同的输出:

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

1. I don't think python has a built-in Sorted sets. 1.我认为python没有内置的排序集。 How about something like this?这样的事情怎么样?

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

2.Java TreeSet is an implementation of the abstraction called SortedSet . 2.Java TreeSet是一个名为SortedSet的抽象的实现。 Basic types will be sorted on natural order.A TreeSet instance performs all key comparisons using its compareTo (or compare) method.So your custom keys should implement proper compareTo基本类型会自然order.A进行排序TreeSet情况下使用它的对所有键进行比较(或比较)method.So您的自定义键应该实施适当compareTo

If what you want is a set that always iterates in sorted-order, this might get you most of the way there:如果你想要的是一个总是按排序顺序迭代的集合,这可能会让你获得大部分方法:

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))

When you are coming with java treeset:当您使用 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