如果项>1,则为列表中的相等项指定一个唯一的数字

2024-05-20 19:12:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我做了一个功能,但我不满意的代码数量。最终的结果是好的,但我相信它可以变得容易得多,只是我不知道怎么做。你知道吗

功能:如果列表中的相等项大于1,则所有相等项都将获得唯一的集合编号。下面我对最终结果进行了单元测试。我对这门课不满意。有人能告诉我怎样才能更好地实施吗。你知道吗

import unittest


class Curtain(object):
  def __init__(self, type, fabric, number):
      self.type = type
      self.fabric = fabric
      self.number = number
      self.set_number = None

  def __str__(self):
      return '%s %s %s %s' % (self.number, self.type, self.fabric, self.set_name)

  def __eq__(self, other):
      return self.type == other.type and self.fabric == other.fabric

class CreatSet(object):
  def make_unique(self, original_list):
      checked = []
      for e in original_list:
          # If curtain: type and fabric is equal
          if e not in checked:
              checked.append(e)
      return checked

  def create_set(self, curtains):
      # Uniuqe items in list
      unique_list = self.make_unique(curtains)
      result = []
      for x in unique_list:
          # Create set list
          set_range = []
          for y in curtains:
              if y == x:
                  set_range.append(y)
          # Add set range into list
          result.append(set_range)

      # Create set number
      set_result = []
      set_number = 0
      for x in result:
          if len(x) == 1:
              set_result.append(x[0])
          else:
              set_number += 1
              for y in x:
                  y.set_number = set_number
                  set_result.append(y)
      # Return list ordered by number
      return sorted(set_result, key=lambda curtain: curtain.number)

class TestCreateSet(unittest.TestCase):
    def setUp(self):
      self.curtains = []
      self.curtains.append(Curtain('pleatcurtain', 'pattern', 0))
      self.curtains.append(Curtain('pleatcurtain', 'plain', 1))
      self.curtains.append(Curtain('pleatcurtain', 'pattern', 2))
      self.curtains.append(Curtain('foldcurtain', 'pattern', 3))
      self.curtains.append(Curtain('pleatcurtain', 'plain', 4))
      self.curtains.append(Curtain('foldcurtain', 'plain', 5))
      self.curtains.append(Curtain('pleatcurtain', 'pattern', 6))
      self.curtains.append(Curtain('foldcurtain', 'pattern', 7))

   def test_auto_set(self):
      creat_set = CreatSet()
      result = creat_set.create_set(self.curtains)
      # Creating set
      self.assertEqual(result[0].set_number, 1)  # pleatcurtain, pattern
      self.assertEqual(result[1].set_number, 2)  # pleatcurtain, plain
      self.assertEqual(result[2].set_number, 1)  # pleatcurtain, pattern
      self.assertEqual(result[3].set_number, 3)  # foldcurtain, pattern
      self.assertEqual(result[4].set_number, 2)  # pleatcurtain, plain
      self.assertEqual(result[5].set_number, None)  # foldcurtain, plain
      self.assertEqual(result[6].set_number, 1)  # pleatcurtain, pattern
      self.assertEqual(result[7].set_number, 3)  # foldcurtain, pattern

 if __name__ == '__main__':
    unittest.main()

Tags: inselfnumberdeftyperesultlistfabric
1条回答
网友
1楼 · 发布于 2024-05-20 19:12:37

以下是我的建议。此响应的开头假设您实际上更喜欢使用单个VideoView。如果情况并非如此,请参见最后的注释

为视频制作一个资源URI队列。比如:

// "list" is fine for this
List<String> videoUris = new ArrayList<>();

现在,编写一个播放视频的代码:

public void playVideo(final String videoUri) {
    // hook up to video view, etc.
}

从这里,你可能有两个选择:

从完成回调

一种方法是监听视频完成回调,然后执行以下操作:

public void onVideoCompletedCallback(final String completedVideoUri) {
    if (!videoUris.isEmpty()) {
        playVideo(videoUris.remove(0));
    }
}

从后台线程

或者,如果将playVideo()实现为阻塞,则可能会运行一个线程来循环它们

new Thread() {
    @Override
    public void run() {
        while (!videoUris.isEmpty()) {
            // assume playVideo() blocks until the video
            // is done playing.
            playVideo(videoUris.remove(0));
        }
    }
}.start();

在这两种情况下,我只提出了一些可行的方法。在Android上,将它们转换为特定的平台绑定仍有一些工作要做

但是如果你仍然完全迷路了,从^{}开始,这可能是我上面所说的回调的一个大致替代品

在Android O上,使用内置队列

事实上,由于我刚刚调出了那个doco,看起来MediaController实际上已经支持Android O预览版的队列。所以,第三种选择,在Android O上:使用^{}。但显然,从2017年4月起,几乎没有人会在这里使用Android O Previous,因此选项3更具学术性而非实用性

使用k-many视频视图

如果您确实需要并且想要这样做,那么调整上面的代码以使用SortedMap。地图将从资源uri到视图id。换句话说,从uri到视频源,再到视频视图的android id,在其中播放它。之所以选择SortedMap而不是HashMap,是因为它会将视频的顺序保留为您选择播放它们的顺序

Map<String, Integer> videoToViewMap = new SortedMap<>();
videoToViewMap.put("android://blah/blah/video.mp4", R.id.videoView1);
// ... more

例如,对过去是videoUris的调用中有几个是相同的isEmpty()。但是,当然,您需要编写从/map/中删除第一项的逻辑,而不是执行.remove()之类的操作

相关问题 更多 >