从python中的列表中获取唯一值[重复]

2024-12-11 08:47:00
admin
原创
170
摘要:问题描述:我想从以下列表中获取唯一值:['nowplaying', 'PBS', 'PBS', 'nowplaying', 'job', 'debate', 'thenandnow'] 我需要的输出是:['nowplaying', 'PBS', 'job', 'debate', 'thenandnow'] 此...

问题描述:

我想从以下列表中获取唯一值:

['nowplaying', 'PBS', 'PBS', 'nowplaying', 'job', 'debate', 'thenandnow']

我需要的输出是:

['nowplaying', 'PBS', 'job', 'debate', 'thenandnow']

此代码有效:

output = []
for x in trends:
    if x not in output:
        output.append(x)
print(output)

我应该使用更好的解决方案吗?


解决方案 1:

首先正确声明列表,以逗号分隔。您可以通过将列表转换为集合来获取唯一值。

mylist = ['nowplaying', 'PBS', 'PBS', 'nowplaying', 'job', 'debate', 'thenandnow']
myset = set(mylist)
print(myset)

如果进一步将其用作列表,则应通过执行以下操作将其转换回列表:

mynewlist = list(myset)

另一种可能,可能更快的是从一开始就使用集合,而不是列表。那么您的代码应该是:

output = set()
for x in trends:
    output.add(x)
print(output)

正如已经指出的那样,集合不保持原始顺序。如果您需要它,则应寻找有序集合实现(有关详细信息,请参阅此问题)。

解决方案 2:

为了与我使用的类型保持一致:

mylist = list(set(mylist))

解决方案 3:

如果我们需要保持元素顺序,那么如何:

used = set()
mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = [x for x in mylist if x not in used and (used.add(x) or True)]

还有一个使用reduce和不使用临时used变量的解决方案。

mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = reduce(lambda l, x: l.append(x) or l if x not in l else l, mylist, [])

更新-2020 年 12 月-也许是最好的方法!

从 python 3.7 开始,标准dict保留插入顺序。

在 3.7 版中更改:保证字典顺序与插入顺序一致。此行为是从 3.6 版开始的 CPython 实现细节。

因此这使我们能够进行dict.fromkeys()重复数据删除!

注意:感谢@rlat在评论中向我们提供此方法!

mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = list(dict.fromkeys(mylist))

就速度而言 - 对我来说,它足够快且足够易读,可以成为我最喜欢的新方法!

更新 - 2019 年 3 月

第三种解决方案很巧妙,但是有点慢,因为.index是 O(n)。

mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = [x for i, x in enumerate(mylist) if i == mylist.index(x)]

更新 - 2016 年 10 月

另一个解决方案是reduce,但这次没有使用.append,这使得它更易于阅读和理解。

mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
unique = reduce(lambda l, x: l+[x] if x not in l else l, mylist, [])
#which can also be writed as:
unique = reduce(lambda l, x: l if x in l else l+[x], mylist, [])

注意:请记住,我们获得的可读性越高,脚本的性能就越差。除非dict.fromkeys()是特定于 Python 3.7+ 的方法。

import timeit

setup = "mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']"

#10x to Michael for pointing out that we can get faster with set()
timeit.timeit('[x for x in mylist if x not in used and (used.add(x) or True)]', setup='used = set();'+setup)
0.2029558869980974

timeit.timeit('[x for x in mylist if x not in used and (used.append(x) or True)]', setup='used = [];'+setup)
0.28999493700030143

# 10x to rlat for suggesting this approach!   
timeit.timeit('list(dict.fromkeys(mylist))', setup=setup)
0.31227896199925453

timeit.timeit('reduce(lambda l, x: l.append(x) or l if x not in l else l, mylist, [])', setup='from functools import reduce;'+setup)
0.7149233570016804

timeit.timeit('reduce(lambda l, x: l+[x] if x not in l else l, mylist, [])', setup='from functools import reduce;'+setup)
0.7379565160008497

timeit.timeit('reduce(lambda l, x: l if x in l else l+[x], mylist, [])', setup='from functools import reduce;'+setup)
0.7400134069976048

timeit.timeit('[x for i, x in enumerate(mylist) if i == mylist.index(x)]', setup=setup)
0.9154880290006986

回答评论

因为@monica提出了一个很好的问题“这是如何工作的?”。对于所有遇到问题的人来说。我会尝试更深入地解释这是如何工作的以及这里发生了什么魔法 ;)

所以她首先问:

我尝试去理解为什么unique = [used.append(x) for x in mylist if x not in used]它不起作用。

嗯,它确实有效

>>> used = []
>>> mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
>>> unique = [used.append(x) for x in mylist if x not in used]
>>> print used
[u'nowplaying', u'PBS', u'job', u'debate', u'thenandnow']
>>> print unique
[None, None, None, None, None]

问题是我们并没有在变量内部得到想要的结果unique,而只是在used变量内部。这是因为在列表推导期间.append修改了used变量并返回None

因此,为了将结果放入unique变量中,并且仍然使用相同的逻辑.append(x) if x not in used,我们需要将此.append调用移到列表推导的右侧,并只x在左侧返回。

但如果我们太天真,只是这么做:

>>> unique = [x for x in mylist if x not in used and used.append(x)]
>>> print unique
[]

我们将不会得到任何回报。

再次,这是因为该.append方法返回None,并且这给我们的逻辑表达式如下:

x not in used and None

这基本上总是:

  1. Falsex在时计算为used

  2. Nonex不在时,计算为used

在这两种情况下(False/ None),这将被视为falsy值,结果我们将得到一个空列表。

但为什么Nonex不在 时,它的计算结果为 呢used?有人可能会问。

嗯,这是因为 Python 的短路运算符就是这样工作的。

该表达式x and y首先计算 x;如果 x 为假,则返回其值;否则,计算 y 并返回结果值。

因此,当x未使用时(即当其时True),将评估下一部分或表达式used.append(x)并返回其值None) 。

但这就是我们想要的,为了从具有重复的列表中获取唯一元素,我们希望.append只有当它们第一次出现时才将它们放入新列表中。

所以我们真正想要的是used.append(x)仅在x不在时进行评估used,也许如果有办法将这个None值变成一个truthy我们就会没事,对吗?

嗯,是的,这就是第二种类型的short-circuit运算符发挥作用的地方。

该表达式x or y首先计算 x;如果 x 为真,则返回其值;否则,计算 y 并返回结果值。

我们知道.append(x)永远是falsy,所以如果我们在它旁边加一个or,我们总是会得到下一部分。这就是为什么我们这样写:

x not in used and (used.append(x) or True)

因此只有当表达式的第一部分是时,我们才能求值 used.append(x)并得到True结果。(x not in used)True

在第二种方法中我们可以看到类似的方式reduce

(l.append(x) or l) if x not in l else l
#similar as the above, but maybe more readable
#we return l unchanged when x is in l
#we append x to l and return l when x is not in l
l if x in l else (l.append(x) or l)

我们:

  1. 附加xl并返回lx不在 时的情况l。由于or语句.append被评估并l在之后返回。

  2. l当处于xl

解决方案 4:

Python 列表:

>>> a = ['a', 'b', 'c', 'd', 'b']

要获得独特的项目,只需将其转换为一个集合(如果需要,您可以将其转换回列表):

>>> b = set(a)
>>> print(b)
{'b', 'c', 'd', 'a'}

解决方案 5:

您的输出变量是什么类型?

Python集合就是您所需要的。像这样声明输出:

output = set()  # initialize an empty set

并且您已准备好添加元素output.add(elem)并确保它们是唯一的。

警告:集合不会保留列表的原始顺序。

解决方案 6:

删除重复项的选项可能包括以下通用数据结构:

  • 集合:无序、唯一元素

  • 有序集:有序、唯一的元素

以下是在 Python 中快速获取其中任一个的总结。

鉴于

from collections import OrderedDict


seq = [u"nowplaying", u"PBS", u"PBS", u"nowplaying", u"job", u"debate", u"thenandnow"]

代码

选项 1 - A set(无序):

list(set(seq))
# ['thenandnow', 'PBS', 'debate', 'job', 'nowplaying']
    

Python 没有有序集,但是这里有一些方法可以模仿有序集。

选项 2 - OrderedDict(按顺序插入):

list(OrderedDict.fromkeys(seq))
# ['nowplaying', 'PBS', 'job', 'debate', 'thenandnow']

选项 3 - a (按顺序插入),Python 3.6+ 中的默认选项。请参阅此文章dict中的更多详细信息:

list(dict.fromkeys(seq))
# ['nowplaying', 'PBS', 'job', 'debate', 'thenandnow']

注意:列出的元素必须是可哈希的。请参阅此博客文章中后一个示例的详细信息。此外,请参阅 R. Hettinger 关于同一技术的帖子;保序字典是从他的一个早期实现扩展而来的。另请参阅有关全序的更多信息。

解决方案 7:

维持秩序:

# oneliners
# slow -> . --- 14.417 seconds ---
[x for i, x in enumerate(array) if x not in array[0:i]]

# fast -> . --- 0.0378 seconds ---
[x for i, x in enumerate(array) if array.index(x) == i]

# multiple lines
# fastest -> --- 0.012 seconds ---
uniq = []
[uniq.append(x) for x in array if x not in uniq]
uniq

顺序不重要:

# fastest-est -> --- 0.0035 seconds ---
list(set(array))

解决方案 8:

从列表中获取唯一元素

mylist = [1,2,3,4,5,6,6,7,7,8,8,9,9,10]

使用集合中的简单逻辑 - 集合是项目的唯一列表

mylist=list(set(mylist))

In [0]: mylist
Out[0]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

使用简单逻辑

newList=[]
for i in mylist:
    if i not in newList:
        newList.append(i)

In [0]: mylist
Out[0]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

使用 pop 方法 ->pop 删除最后一个或索引项并将其显示给用户。视频

k=0
while k < len(mylist):
    if mylist[k] in mylist[k+1:]:
        mylist.pop(mylist[k])
    else:
        k=k+1

In [0]: mylist
Out[0]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

使用 Numpy

import numpy as np
np.unique(mylist)

In [0]: mylist
Out[0]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

参考

解决方案 9:

如果你在代码中使用 numpy(对于大量数据来说这可能是一个不错的选择),请查看numpy.unique

>>> import numpy as np
>>> wordsList = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
>>> np.unique(wordsList)
array([u'PBS', u'debate', u'job', u'nowplaying', u'thenandnow'], 
      dtype='<U10')

http://docs.scipy.org/doc/numpy/reference/ generated /numpy.unique.html )

可以看到,numpy 不仅支持数值数据,还可以支持字符串数组。当然,结果是一个 numpy 数组,但这并不重要,因为它仍然表现得像一个序列:

>>> for word in np.unique(wordsList):
...     print word
... 
PBS
debate
job
nowplaying
thenandnow

如果您确实想要恢复原始的 Python 列表,您可以随时调用 list()。

但是,结果会自动排序,如上面的代码片段所示。如果需要保留列表顺序,请查看numpy unique without sort 。

解决方案 10:

set - 唯一元素的无序集合。元素列表可以传递给 set 的构造函数。因此,传递具有重复元素的列表,我们获取具有唯一元素的 set 并将其转换回列表,然后获取具有唯一元素的列表。我无法谈论性能和内存开销,但我希望,对于小列表来说,这不是那么重要。

list(set(my_not_unique_list))

簡單又短小。

解决方案 11:

仅使用列表压缩的相同顺序唯一列表。

> my_list = [1, 2, 1, 3, 2, 4, 3, 5, 4, 3, 2, 3, 1]
> unique_list = [
>    e
>    for i, e in enumerate(my_list)
>    if my_list.index(e) == i
> ]
> unique_list
[1, 2, 3, 4, 5]

enumerates将索引i和元素e作为给出tuple

my_list.index返回 的第一个索引e。如果第一个索引不是,i则当前迭代e不是e列表中的第一个。

编辑

我应该指出,从性能角度来看,这不是一个好方法。这只是一种仅使用列表压缩来实现的方法。

解决方案 12:

首先,您给出的例子不是一个有效的列表。

example_list = [u'nowplaying',u'PBS', u'PBS', u'nowplaying', u'job', u'debate',u'thenandnow']

假设上面是示例列表。然后您可以使用以下配方,给出 itertools 示例文档,该文档可以返回唯一值并保留您似乎需要的顺序。这里的可迭代对象是 example_list

from itertools import ifilterfalse

def unique_everseen(iterable, key=None):
    "List unique elements, preserving order. Remember all elements ever seen."
    # unique_everseen('AAAABBBCCDAABBB') --> A B C D
    # unique_everseen('ABBCcAD', str.lower) --> A B C D
    seen = set()
    seen_add = seen.add
    if key is None:
        for element in ifilterfalse(seen.__contains__, iterable):
            seen_add(element)
            yield element
    else:
        for element in iterable:
            k = key(element)
            if k not in seen:
                seen_add(k)
                yield element

解决方案 13:

作为奖励,Counter这是一种获取唯一值和每个值的计数的简单方法:

from collections import Counter
l = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
c = Counter(l)

解决方案 14:

通过使用 Python Dictionary 的基本属性:

inp=[u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
d={i for i in inp}
print d

输出将是:

set([u'nowplaying', u'job', u'debate', u'PBS', u'thenandnow'])

解决方案 15:

def get_distinct(original_list):
    distinct_list = []
    for each in original_list:
        if each not in distinct_list:
            distinct_list.append(each)
    return distinct_list

解决方案 16:

set可以帮助您从列表中过滤掉重复的元素。它对strinttuple元素很有效,但如果您的列表包含dict或其他list元素,那么您最终会遇到TypeError异常。

这是一个通用的保序解决方案,用于处理某些(并非全部)不可散列的类型:

def unique_elements(iterable):
    seen = set()
    result = []
    for element in iterable:
        hashed = element
        if isinstance(element, dict):
            hashed = tuple(sorted(element.iteritems()))
        elif isinstance(element, list):
            hashed = tuple(element)
        if hashed not in seen:
            result.append(element)
            seen.add(hashed)
    return result

解决方案 17:

def setlist(lst=[]):
   return list(set(lst))

解决方案 18:

如果您想从列表中获取唯一元素并保持其原始顺序,那么您可以使用OrderedDictPython 标准库中的数据结构:

from collections import OrderedDict

def keep_unique(elements):
    return list(OrderedDict.fromkeys(elements).keys())

elements = [2, 1, 4, 2, 1, 1, 5, 3, 1, 1]
required_output = [2, 1, 4, 5, 3]

assert keep_unique(elements) == required_output

事实上,如果你使用的是 Python ≥ 3.6,那么你可以使用 plain dict

def keep_unique(elements):
    return list(dict.fromkeys(elements).keys())

在引入“紧凑”的字典表示后,这已成为可能。在这里查看。尽管这“被视为实现细节,不应依赖”。

解决方案 19:

要从列表中获取唯一值,使用以下代码:

trends = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
output = set(trends)
output = list(output)

重要提示:
如果列表中的任何项目不可哈希,则上述方法将不起作用(对于可变类型,例如list或dict)。

trends = [{'super':u'nowplaying'}, u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']
output = set(trends)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  TypeError: unhashable type: 'dict'

这意味着您必须确保trends列表始终只包含可哈希的项目,否则您必须使用更复杂的代码:

from copy import deepcopy

try:
    trends = [{'super':u'nowplaying'}, [u'PBS',], [u'PBS',], u'nowplaying', u'job', u'debate', u'thenandnow', {'super':u'nowplaying'}]
    output = set(trends)
    output = list(output)
except TypeError:
    trends_copy = deepcopy(trends)
    while trends_copy:
        trend = trends_copy.pop()
        if trends_copy.count(trend) == 0:
            output.append(trend)
print output

解决方案 20:

令我惊讶的是,到目前为止还没有人给出直接的保序答案:

def unique(sequence):
    """Generate unique items from sequence in the order of first occurrence."""
    seen = set()
    for value in sequence:
        if value in seen:
            continue

        seen.add(value)

        yield value

它将生成值,因此它不仅可以用于列表,例如unique(range(10))。要获取列表,只需调用list(unique(sequence)),如下所示:

>>> list(unique([u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']))
[u'nowplaying', u'PBS', u'job', u'debate', u'thenandnow']

它要求每个项目都是可哈希的,而不仅仅是可比较的,但 Python 中的大多数东西都是可哈希的,并且是 O(n) 而不是 O(n^2),因此对于长列表也可以正常工作。

解决方案 21:

除了前面提到的可以将列表转换为集合的答案之外,您还可以通过这种方式进行转换

mylist = [u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenadnow']
mylist = [i for i in set(mylist)]

输出将是

[u'nowplaying', u'job', u'debate', u'PBS', u'thenadnow']

但秩序将不会被保留。

另一个更简单的答案可能是(不使用集合)

>>> t = [v for i,v in enumerate(mylist) if mylist.index(v) == i]
[u'nowplaying', u'PBS', u'job', u'debate', u'thenadnow']

解决方案 22:

  1. 在代码开始时,只需将输出列表声明为空:output=[]

  2. 除了您的代码之外,您还可以使用此代码trends=list(set(trends))

解决方案 23:

您可以使用集合。为了清楚起见,我正在解释列表和集合之间的区别。集合是唯一元素的无序集合。列表是元素的有序集合。所以,

    unicode_list=[u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job',u'debate', u'thenandnow']
    list_unique=list(set(unicode_list))
    print list_unique
[u'nowplaying', u'job', u'debate', u'PBS', u'thenandnow']

但是:不要使用 list/set 来命名变量。这将导致错误:例如:在上面的例子中,应该使用 list 而不是 unicode_list。

list=[u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job',u'debate', u'thenandnow']
        list_unique=list(set(list))
        print list_unique
    list_unique=list(set(list))
TypeError: 'list' object is not callable

解决方案 24:

使用 set 对列表进行去重,并以列表形式返回

def get_unique_list(lst):
        if isinstance(lst,list):
            return list(set(lst))

解决方案 25:

Set 是无序唯一元素的集合。因此,你可以按如下方式使用 set 来获取唯一列表:

unique_list = list(set([u'nowplaying', u'PBS', u'PBS', u'nowplaying', u'job', u'debate', u'thenandnow']))

解决方案 26:

我的解决方案是检查内容的唯一性但保留原始顺序:

def getUnique(self):
    notunique = self.readLines()
    unique = []
    for line in notunique: # Loop over content
        append = True # Will be set to false if line matches existing line
        for existing in unique:
            if line == existing: # Line exists ? do not append and go to the next line
                append = False
                break # Already know file is unique, break loop
        if append: unique.append(line) # Line not found? add to list
    return unique

编辑:使用字典键来检查是否存在可能会更有效,而不是对每一行进行整个文件循环,我不会对大型集合使用我的解决方案。

解决方案 27:

我知道这是一个老问题,但这是我独特的解决方案:类继承!:

class UniqueList(list):
    def appendunique(self,item):
        if item not in self:
            self.append(item)
            return True
        return False

然后,如果您想将项目唯一地附加到列表中,只需在 UniqueList 上调用 appendunique 即可。由于它继承自列表,因此它基本上就像列表一样,因此您可以使用 index() 等函数。并且由于它返回 true 或 false,因此您可以确定附加是成功(唯一项目)还是失败(已在列表中)。

要从列表中获取项目的唯一列表,请使用 for 循环将项目附加到 UniqueList(然后复制到列表)。

使用代码示例:

unique = UniqueList()

for each in [1,2,2,3,3,4]:
    if unique.appendunique(each):
        print 'Uniquely appended ' + str(each)
    else:
        print 'Already contains ' + str(each)

印刷:

Uniquely appended 1
Uniquely appended 2
Already contains 2
Uniquely appended 3
Already contains 3
Uniquely appended 4

复制到列表:

unique = UniqueList()

for each in [1,2,2,3,3,4]:
    unique.appendunique(each)

newlist = unique[:]
print newlist

印刷:

[1, 2, 3, 4]

解决方案 28:

对于长数组

s = np.empty(len(var))

s[:] = np.nan

for  x in  set(var):

    x_positions = np.where(var==x)

    s[x_positions[0][0]]=x


sorted_var=s[~np.isnan(s)]

解决方案 29:

尝试这个函数,它与您的代码类似,但它是一个动态范围。

def unique(a):

    k=0
    while k < len(a):
        if a[k] in a[k+1:]:
            a.pop(k)
        else:
            k=k+1



    return a

解决方案 30:

使用以下函数:

def uniquefy_list(input_list):
"""
This function  takes a list as input and return a list containing only unique elements from the input list

"""
output_list=[]
for elm123 in input_list:
    in_both_lists=0
    for elm234 in output_list:
        if elm123 == elm234:
            in_both_lists=1
            break
    if in_both_lists == 0:
        output_list.append(elm123)

return output_list
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1603  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1369  
  信创产品在政府采购中的占比分析随着信息技术的飞速发展以及国家对信息安全重视程度的不断提高,信创产业应运而生并迅速崛起。信创,即信息技术应用创新,旨在实现信息技术领域的自主可控,减少对国外技术的依赖,保障国家信息安全。政府采购作为推动信创产业发展的重要力量,其对信创产品的采购占比情况备受关注。这不仅关系到信创产业的发展前...
信创和国产化的区别   30  
  信创,即信息技术应用创新产业,旨在实现信息技术领域的自主可控,摆脱对国外技术的依赖。近年来,国货国用信创发展势头迅猛,在诸多领域取得了显著成果。这一发展趋势对科技创新产生了深远的推动作用,不仅提升了我国在信息技术领域的自主创新能力,还为经济社会的数字化转型提供了坚实支撑。信创推动核心技术突破信创产业的发展促使企业和科研...
信创工作   28  
  信创技术,即信息技术应用创新产业,旨在实现信息技术领域的自主可控与安全可靠。近年来,信创技术发展迅猛,对中小企业产生了深远的影响,带来了诸多不可忽视的价值。在数字化转型的浪潮中,中小企业面临着激烈的市场竞争和复杂多变的环境,信创技术的出现为它们提供了新的发展机遇和支撑。信创技术对中小企业的影响技术架构变革信创技术促使中...
信创国产化   35  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用