Python的defaultdict的模拟?Python、defaultdict

2023-09-04 01:06:36 作者:安尐熙°

有Python的 defaultdict ?我觉得有用写短code,例如。计数频率:

 >>>字=生存还是毁灭.split()
>>>打印字
['到','是','或','不','到','是']
>>>从收藏品进口defaultdict
>>>频率= defaultdict(INT)
>>>字的话:
...频率[文字​​] + = 1
...
>>>打印频率
defaultdict(小于类型int>中{'不':1,'到'2'或':1,'是':2})
 

所以,最好是在C#中,我可以写的:

  VAR频率=新DefaultDictionary<字符串,INT>(()= 0);
的foreach(文字串字)
{
    频率[文字​​] + = 1
}
 

解决方案

东西让你开始。我基本上只是改变了索引。因为我不知道Python的完整功能 defaultdict 我不能进一步改善。你给出的示例将工作。

 公共类DefaultDictionary< TKEY的,TValue> :IDictionary的< TKEY的,TValue>
{
    私人只读Func键< TValue> _defaultSelector;
    私人只读字典< TKEY的,TValue> _values​​ =新字典< TKEY的,TValue>();

    公共DefaultDictionary(Func键< TValue> defaultSelector)
    {
        _defaultSelector = defaultSelector;
    }

    公众的IEnumerator< KeyValuePair< TKEY的,TValue>>的GetEnumerator()
    {
        返回_values​​.GetEnumerator();
    }

    IEnumerator的IEnumerable.GetEnumerator()
    {
        返回的GetEnumerator();
    }

    公共无效添加(KeyValuePair< TKEY的,TValue>项目)
    {
        ((IDictionary的< TKEY的,TValue>)_值)。新增(项目);
    }

    公共无效清除()
    {
        _values​​.Clear();
    }

    公共BOOL包含(KeyValuePair< TKEY的,TValue>项目)
    {
        返程((IDictionary的< TKEY的,TValue>)_值)。载(项目);
    }

    公共无效CopyTo从(KeyValuePair< TKEY的,TValue> []数组,诠释arrayIndex)
    {
        ((IDictionary的< TKEY的,TValue>)_值).CopyTo(阵列,arrayIndex);
    }

    公共BOOL删除(KeyValuePair< TKEY的,TValue>项目)
    {
        返回((IDictionary的< TKEY的,TValue>)_值)上卸下摆臂(项目);
    }

    公众诠释计数{{返回_values​​.Count; }}
    公共BOOL的IsReadOnly {{返回((IDictionary的< TKEY的,TValue>)_values​​).IsReadOnly; }}
    公共BOOL的containsKey(TKEY的键)
    {
        返回_values​​.ContainsKey(键);
    }

    公共无效添加(TKEY的关键,TValue值)
    {
        _values​​.Add(键,值);
    }

    公共BOOL删除(TKEY的键)
    {
        返回_values​​.Remove(键);
    }

    公共BOOL TryGetValue(TKEY的钥匙,走出TValue值)
    {
        返回_values​​.TryGetValue(键,超时值);
    }

    公共TValue这[TKEY的关键]
    {
        得到
        {
            如果(!_values​​.ContainsKey(键))
            {
                _values​​.Add(键,_defaultSelector());
            }
            返回_values​​ [关键];
        }
        组
        {
            如果(!_ values​​.ContainsKey(键))
            {
                _values​​.Add(键,_defaultSelector());
            }
            _values​​ [关键] =价值;
        }
    }

    公众的ICollection< TKEY的>键{{返回_values​​.Keys; }}
    公众的ICollection< TValue>值{{返回_values​​.Values​​; }}

    公共字典< TKEY的,TValue> ToDictionary()
    {
        返回新字典< TKEY的,TValue>(_值);
    }
}
 
Python中defaultdict的使用

Is there a .NET analogue of Python's defaultdict? I find it useful to write short code, eg. counting frequencies:

>>> words = "to be or not to be".split()
>>> print words
['to', 'be', 'or', 'not', 'to', 'be']
>>> from collections import defaultdict
>>> frequencies = defaultdict(int)
>>> for word in words:
...     frequencies[word] += 1
... 
>>> print frequencies
defaultdict(<type 'int'>, {'not': 1, 'to': 2, 'or': 1, 'be': 2})

So ideally in C# I could write:

var frequencies = new DefaultDictionary<string,int>(() => 0);
foreach(string word in words)
{
    frequencies[word] += 1
}

解决方案

Something to get you started. I basically just changed the this indexer. Since I don't know the complete functionality of python's defaultdict I cannot improve it further. Your given example will work.

public class DefaultDictionary<TKey, TValue> : IDictionary<TKey,TValue>
{
    private readonly Func<TValue> _defaultSelector;
    private readonly Dictionary<TKey, TValue> _values = new Dictionary<TKey, TValue>();

    public DefaultDictionary(Func<TValue> defaultSelector)
    {
        _defaultSelector = defaultSelector;
    }

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
    {
        return _values.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public void Add(KeyValuePair<TKey, TValue> item)
    {
        ((IDictionary<TKey,TValue>)_values).Add(item);
    }

    public void Clear()
    {
        _values.Clear();
    }

    public bool Contains(KeyValuePair<TKey, TValue> item)
    {
        return ((IDictionary<TKey,TValue>)_values).Contains(item);
    }

    public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
    {
        ((IDictionary<TKey, TValue>)_values).CopyTo(array, arrayIndex);
    }

    public bool Remove(KeyValuePair<TKey, TValue> item)
    {
        return ((IDictionary<TKey, TValue>)_values).Remove(item);
    }

    public int Count { get { return _values.Count; } }
    public bool IsReadOnly { get { return ((IDictionary<TKey, TValue>) _values).IsReadOnly; } }
    public bool ContainsKey(TKey key)
    {
        return _values.ContainsKey(key);
    }

    public void Add(TKey key, TValue value)
    {
        _values.Add(key, value);
    }

    public bool Remove(TKey key)
    {
        return _values.Remove(key);
    }

    public bool TryGetValue(TKey key, out TValue value)
    {
        return _values.TryGetValue(key, out value);
    }

    public TValue this[TKey key]
    {
        get
        {
            if (!_values.ContainsKey(key))
            {
                _values.Add(key, _defaultSelector());
            }
            return _values[key];
        }
        set
        {
            if(!_values.ContainsKey(key))
            {
                _values.Add(key, _defaultSelector());
            }
            _values[key] = value;
        }
    }

    public ICollection<TKey> Keys { get { return _values.Keys; } }
    public ICollection<TValue> Values { get { return _values.Values; } }

    public Dictionary<TKey, TValue> ToDictionary()
    {
        return new Dictionary<TKey, TValue>(_values);
    }
}