在列表字典

时间:2017-01-05 07:46:46

标签: python dictionary

我为我的目的创建了一个数据结构,这是一个简单的字典,其中包含值列表作为数据:

{'Procedure_name': ('compound', 'hardware', 'tempval', 'colorval', 'energyval'), .....}

想象一系列程序,其中混合2种化合物,记录温度变化,势能,颜色变化等,这就是字典中每个条目所代表的内容。

实现过滤器实现的最佳方法是什么?这是想要实现的一个例子。我的过滤器主要用于使用少量参数(如复合,硬件),无论是单个还是组合

dataset = {'Att1_Cl': ('carb', 'Spectrometer_v1', '33', '0.25', '445'), 
    'Att1_Na': ('carb', 'Spectrometer_v1', '34.2', '0.21', '401'), 
    'Att1_Si': ('alc', 'Photometer_V2', '32.1', '0.43', '521'), 
    'Att1_Cr': ('carb', 'Photometer_V3', '32.5', '0.49', '511')}

def filter_data(filter)
    ....
    return filtered_data # the entry from the dictionary that satisfy the condition

作为输出示例:

print (filter_data (['carb']))

Att1_Cl
('carb', 'Spectrometer_v1', '33', '0.25', '445')
Att1_Na
('carb', 'Spectrometer_v1', '34.2', '0.21', '401') 
Att1_Cr
('carb', 'Photometer_V3', '32.5', '0.49', '511')

print (filter_data (['Spectrometer_v1']))

Att1_Cl
('carb', 'Spectrometer_v1', '33', '0.25', '445')
Att1_Na
('carb', 'Spectrometer_v1', '34.2', '0.21', '401')

print (filter_data (['carb', 'Photometer_V3']))

Att1_Cr
('carb', 'Photometer_V3', '32.5', '0.49', '511')

我在考虑使用列表作为可能的参数,并比较数据集中的每个条目;但我找不到一种有效的方法来完成这项工作。这是我的第一个方法

def filter_data(filter):

    for procedure in dataset:
        single_dataset = dataset[procedure]
        if filter in single_dataset:
            print(procedure)
            print(single_dataset)

如果我有一个条目,但是如果我在过滤器列表中有多个条目,则此方法有效;我必须在数据集上进行多次传递,如果我将向数据结构添加更多参数,这不是真正有效也不可扩展。 我想到的另一个选择是保存预先制作的过滤器,通过传递给函数的filter参数调用,但从维护代码的角度来看这是一场噩梦,因为过滤器中的每个更改都必须是硬编码。

3 个答案:

答案 0 :(得分:0)

您可以将它们存储为嵌套字典,而不是将参数存储为list。这将使过滤器实现更容易,并且还允许您基于参数而不仅仅是它们的值进行过滤。假设您要查找tempval == '30'的所有过程。如果您致电filter_data (['30']),您可能会获得energyval'30'的程序。

过滤嵌套dict的一种方法是在if块内使用带all的生成器表达式。您可以轻松地将生成器转换为所需的返回类型,或在找到第一个匹配时终止过滤:

dataset = {
    'Att1_Cl': {'compound': 'carb', 'hardware': 'Spectrometer_v1', 'tempval': '33', 'colorval': '0.25', 'energyval': '445'}, 
    'Att1_Na': {'compound': 'carb', 'hardware': 'Spectrometer_v1', 'tempval': '34.2', 'colorval': '0.21', 'energyval': '401'}, 
    'Att1_Si': {'compound': 'alc', 'hardware': 'Photometer_V2', 'tempval': '32.1', 'colorval': '0.43', 'energyval': '521'}, 
    'Att1_Cr': {'compound': 'carb', 'hardware': 'Photometer_V3', 'tempval': '32.5', 'colorval': '0.49', 'energyval': '511'}
}

def filter_data(f):
    return ((k, v) for k, v in dataset.items() if all(v[fk] == fv for fk, fv in f.items()))

print(list(filter_data({'compound': 'carb', 'hardware': 'Spectrometer_v1'})))

输出:

[('Att1_Cl', {'energyval': '445', 'tempval': '33', 'hardware': 'Spectrometer_v1', 'compound': 'carb', 'colorval': '0.25'}), 
 ('Att1_Na', {'energyval': '401', 'tempval': '34.2', 'hardware': 'Spectrometer_v1', 'compound': 'carb', 'colorval': '0.21'})]

答案 1 :(得分:0)

我正在开发一个需要过滤功能的聊天机器人,我相信这些功能与您的需求类似。我维护着一个回复文章的数据库&#39;形式为<<response template>> #tag1 #tag2 ... #tagN的形式。例如:&#34;你好,你好吗? #greeting #wellbeing&#34;。

这允许我在chatbot中实现逻辑,它尝试通过标记要求系统组成适当的响应,该系统支持&#34;和&#34;和&#34;或&#34;不合要求。这些子需求可以嵌套以形成树结构。

可以从字符串中解析这些标记要求。例如,字符串&#34;表达,可爱;表达,快乐&#34;任何包含 #emote#cute #emote#happy的回复文章都可以满足。

在您的情况下,响应文章类似于过程名称,以及过程属性的响应分类。您可以采用与我的方法类似的方法来指定诸如&#34;碳水化合物,光谱仪*; alk,光谱仪*&#34;匹配所有涉及光谱仪的程序,并涉及“碳水化合物”和“碳水化合物”。或者&#39; alk&#39; (或两者兼有)。

我的代码是用C#编写的,但希望你仍然觉得它很有用。 This page可能是开始寻找的最佳位置,您可以在this test class.

中查看其用法示例

为了方便和冗余,我将复制下面的代码。

<强>实施

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Mofichan.DataAccess
{
    /// <summary>
    /// Represents a tag requirement.
    /// <para></para>
    /// These will typically be used to filter the kind of responses
    /// Mofichan will choose to respond with based on the tags
    /// associated with each possible response she knows about.
    /// </summary>
    internal interface ITagRequirement
    {
        /// <summary>
        /// Returns whether this <c>ITagRequirement</c> is satisfied by
        /// the provided collection of tags.
        /// </summary>
        /// <param name="tags">The tag collection.</param>
        /// <returns><c>true</c> if <c>this</c> is satisfied; otherwise, <c>false</c>.</returns>
        bool SatisfiedBy(IEnumerable<string> tags);
    }

    /// <summary>
    /// Provides static fields and methods.
    /// </summary>
    internal static class TagRequirement
    {
        internal static readonly char AndSeparator = ',';
        internal static readonly char OrSeparator = ';';

        private static readonly string TagMatch = @"[a-zA-Z0-9\-]+";
        private static readonly string AndMatcher = string.Format(@"((?<and>{0}){1})*(?<and>{0})", TagMatch, AndSeparator);
        private static readonly string OrMatcher = string.Format(@"^((?<or>{0}){1})*(?<or>{0})$", AndMatcher, OrSeparator);

        /// <summary>
        /// Parses a string and returns the represented <see cref="ITagRequirement"/>. 
        /// </summary>
        /// <param name="representation">The tag requirement string representation.</param>
        /// <returns>The represented tag requirement.</returns>
        /// <exception cref="ArgumentException">Thrown if the representation is invalid.</exception>
        public static ITagRequirement Parse(string representation)
        {
            var root = new AnyTagRequirement(from orGroup in GetMatchesFromRegex(representation, OrMatcher, "or")
                                             let andGroup = from tag in GetMatchesFromRegex(orGroup, AndMatcher, "and")
                                                            select new LeafTagRequirement(tag)
                                             let allTagRequirement = new AllTagRequirement(andGroup)
                                             select allTagRequirement);

            return root;
        }

        private static IEnumerable<string> GetMatchesFromRegex(string input, string pattern, string matchName)
        {
            var regex = Regex.Match(input, pattern);

            if (!regex.Success)
            {
                var message = string.Format("Input '{0}' is invalid for pattern '{1}'", input, pattern);
                throw new ArgumentException(message);
            }

            var captures = regex.Groups[matchName].Captures;

            return from i in Enumerable.Range(0, captures.Count)
                   select captures[i].Value;
        }
    }

    internal abstract class CompositeTagRequirement : ITagRequirement
    {
        protected CompositeTagRequirement(IEnumerable<ITagRequirement> children)
        {
            this.Children = children;
        }

        public IEnumerable<ITagRequirement> Children { get; }

        public abstract bool SatisfiedBy(IEnumerable<string> tags);
    }

    internal sealed class AllTagRequirement : CompositeTagRequirement
    {
        public AllTagRequirement(IEnumerable<ITagRequirement> children) : base(children)
        {
        }

        public override bool SatisfiedBy(IEnumerable<string> tags)
        {
            return this.Children.All(it => it.SatisfiedBy(tags));
        }

        public override string ToString()
        {
            return string.Join(TagRequirement.AndSeparator.ToString(), this.Children);
        }
    }

    internal sealed class AnyTagRequirement : CompositeTagRequirement
    {
        public AnyTagRequirement(IEnumerable<ITagRequirement> children) : base(children)
        {
        }

        public override bool SatisfiedBy(IEnumerable<string> tags)
        {
            return this.Children.Any(it => it.SatisfiedBy(tags));
        }

        public override string ToString()
        {
            return string.Join(TagRequirement.OrSeparator.ToString(), this.Children);
        }
    }

    internal sealed class LeafTagRequirement : ITagRequirement
    {
        private readonly string requiredTag;

        public LeafTagRequirement(string tag)
        {
            this.requiredTag = tag;
        }

        public bool SatisfiedBy(IEnumerable<string> tags)
        {
            return tags.Contains(this.requiredTag);
        }

        public override string ToString()
        {
            return this.requiredTag;
        }
    }
}

<强>测试

using System;
using System.Collections.Generic;
using Mofichan.DataAccess;
using Shouldly;
using Xunit;

namespace Mofichan.Tests.DataAccess
{
    public class TagRequirementTests
    {
        public static IEnumerable<object> TagRequirementExamples
        {
            get
            {
                yield return new object[]
                {
                    // Requirement
                    "foo",

                    // Satisfied by
                    new[]
                    {
                        new[] { "foo" },
                    },

                    // Unsatisfied by
                    new[]
                    {
                        new[] { "bar" },
                        new[] { "baz" },
                    },
                };

                yield return new object[]
                {
                    // Requirement
                    "foo;bar",

                    // Satisfied by
                    new[]
                    {
                        new[] { "foo" },
                        new[] { "foo" },
                        new[] { "foo", "bar" },
                    },

                    // Unsatisfied by
                    new[]
                    {
                        new[] { "baz" },
                    },
                };

                yield return new object[]
                {
                    // Requirement
                    "foo,bar;baz",

                    // Satisfied by
                    new[]
                    {
                        new[] { "foo", "bar", "baz" },
                        new[] { "foo", "bar" },
                        new[] { "foo", "baz" },
                        new[] { "baz" },
                    },

                    // Unsatisfied by
                    new[]
                    {
                        new[] { "bar" },
                        new[] { "foo" },
                    },
                };
            }
        }

        [Theory]
        [MemberData(nameof(TagRequirementExamples))]
#pragma warning disable S2368 // Public methods should not have multidimensional array parameters
        public void No_Exception_Should_Be_Thrown_When_Valid_Tag_Requirement_Representation_Is_Parsed(
#pragma warning restore S2368 // Public methods should not have multidimensional array parameters
            string validRepresentation, string[][] _, string[][] __)
        {
            // EXPECT we can parse the valid tag requirement representation without exception.
            TagRequirement.Parse(validRepresentation).ShouldNotBeNull();
        }

        [Theory]
        [InlineData("")]
        [InlineData("@illegal?characters")]
        [InlineData("multiword tag without hyphen")]
        public void Exception_Should_Be_Thrown_When_Invalid_Tag_Requirement_Representation_Is_Parsed(
            string invalidRepresentation)
        {
            // EXPECT that an exception is thrown when we try to parse the invalid representation.
            Assert.Throws<ArgumentException>(() => TagRequirement.Parse(invalidRepresentation));
        }

        [Theory]
        [MemberData(nameof(TagRequirementExamples))]
#pragma warning disable S2368 // Public methods should not have multidimensional array parameters
        public void Tag_Requirements_Should_Declare_Satisfaction_From_Provided_Tags_As_Expected(
#pragma warning restore S2368 // Public methods should not have multidimensional array parameters
            string tagRequirementRepr,
            string[][] expectedSatisfiedBy,
            string[][] expectedUnsatisfiedBy)
        {
            // GIVEN a tag requirement based on the provided representation.
            var tagRequirement = TagRequirement.Parse(tagRequirementRepr);

            // EXPECT that the tag requirement is satisfied by provided groups of tags as appropriate.
            expectedSatisfiedBy.ShouldAllBe(tagGroup => tagRequirement.SatisfiedBy(tagGroup));

            // EXPECT that the tag requirement is unsatisfied by provided groups of tags as appropriate.
            expectedUnsatisfiedBy.ShouldAllBe(tagGroup => !tagRequirement.SatisfiedBy(tagGroup));
        }
    }
}

答案 2 :(得分:0)

single_dataset = ['carb', 'Photometer_V3']

for procedure in dataset:

    s = dataset[procedure]

    if [ x for x in single_dataset if x in s] == single_dataset:

        print procedure,s