Java 的 TreeSet 在 Python 中等效吗?

发布于 2024-08-30 09:12:30 字数 972 浏览 6 评论 0原文

我最近遇到一些 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)))

将受到欢迎。

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.

My questions,

  • Is there an equivalent data structure available for Python?

    • The Java treeset looks basically to be an ordered dictionary that can use a comparator of some sort to achieve this ordering.
  • I see there's a PEP for Py3K for an OrderedDict, but I'm using 2.6.x. There are a bunch of ordered dict implementations out there - anyone in particular that can be recommended?

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.

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

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

Something like,

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

Ideas would be welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

分分钟 2024-09-06 09:12:30

Python 2.7 collections.OrderedDict< /a> 具有指向在 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

The Python 2.7 docs for collections.OrderedDict has a link to a OrderedDict recipe that runs on Python 2.4 or better.

Edit: In regard to sorting: Use key= rather than cmp=. It tends to lead to faster code and moreover, the cmp= keyword has been eliminated in 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. Below, I assume x1 is supposed to be the value in each key-value pair. 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).
For each item in d.items(), the lambda function returns the number 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.

PS. len is a Python builtin function. So as to not clobber that len, I've changed the variable name to length.

三寸金莲 2024-09-06 09:12:30

我最近使用 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

I recently implemented TreeSet for Python using bisect module.

https://github.com/fukatani/TreeSet

Its usage is similar to Java's 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
风和你 2024-09-06 09:12:30

我需要查看一些示例数据,但如果您只是尝试进行加权排序,那么内置的 python Sort() 可以通过两种方式做到这一点。

使用有序的元组和 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)

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.

With well ordered tuples and a key() function:

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.

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)
水水月牙 2024-09-06 09:12:30

1.
我不认为 python 有内置的排序集。
像这样的事情怎么样?

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

2.Java TreeSet 是名为 SortedSet 的抽象的实现。基本类型将按自然顺序排序。TreeSet实例使用其compareTo(或compare)方法执行所有键比较。因此您的自定义键应该实现正确的compareTo

1.
I don't think python has a built-in Sorted sets.
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. 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

没有心的人 2024-09-06 09:12:30

如果您想要的是一个始终按排序顺序迭代的集合,这可能会帮助您实现大部分目标:

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

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))
梦晓ヶ微光ヅ倾城 2024-09-06 09:12:30

当您使用 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] 

When you are coming with java treeset:

 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] 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文